Kaynağa Gözat

Merge branch 'develop' into 'fix/prune-hashtags'

# Conflicts:
#   CHANGELOG.md
cycles-validator
feld 3 yıl önce
ebeveyn
işleme
84f42b92f0
100 değiştirilmiş dosya ile 927 ekleme ve 429 silme
  1. +2
    -1
      .gitignore
  2. +29
    -0
      .gitlab-ci.yml
  3. +8
    -0
      CHANGELOG.md
  4. +1
    -1
      Dockerfile
  5. +2
    -2
      README.md
  6. +1
    -1
      benchmarks/load_testing/activities.ex
  7. +1
    -1
      config/benchmark.exs
  8. +4
    -3
      config/config.exs
  9. +15
    -20
      config/description.exs
  10. +5
    -1
      config/dev.exs
  11. +1
    -1
      config/dokku.exs
  12. +7
    -2
      config/prod.exs
  13. +5
    -1
      config/test.exs
  14. +4
    -4
      docs/configuration/cheatsheet.md
  15. +1
    -1
      docs/development/API/pleroma_api.md
  16. +2
    -2
      docs/installation/alpine_linux_en.md
  17. +2
    -2
      docs/installation/arch_linux_en.md
  18. +2
    -2
      docs/installation/debian_based_en.md
  19. +4
    -4
      docs/installation/debian_based_jp.md
  20. +4
    -4
      docs/installation/freebsd_en.md
  21. +6
    -6
      docs/installation/gentoo_en.md
  22. +3
    -5
      docs/installation/netbsd_en.md
  23. +2
    -2
      docs/installation/openbsd_en.md
  24. +2
    -2
      docs/installation/openbsd_fi.md
  25. +2
    -2
      docs/installation/otp_en.md
  26. +45
    -0
      lib/pleroma/activity/html.ex
  27. +6
    -6
      lib/pleroma/application.ex
  28. +5
    -3
      lib/pleroma/application_requirements.ex
  29. +25
    -1
      lib/pleroma/config/deprecation_warnings.ex
  30. +16
    -14
      lib/pleroma/config/loader.ex
  31. +21
    -19
      lib/pleroma/config/transfer_task.ex
  32. +0
    -2
      lib/pleroma/constants.ex
  33. +24
    -12
      lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex
  34. +2
    -2
      lib/pleroma/emails/admin_email.ex
  35. +9
    -2
      lib/pleroma/emails/user_email.ex
  36. +2
    -2
      lib/pleroma/emoji/formatter.ex
  37. +1
    -1
      lib/pleroma/formatter.ex
  38. +1
    -3
      lib/pleroma/gun.ex
  39. +3
    -3
      lib/pleroma/gun/connection_pool/reclaimer.ex
  40. +5
    -5
      lib/pleroma/gun/connection_pool/worker.ex
  41. +0
    -35
      lib/pleroma/html.ex
  42. +2
    -2
      lib/pleroma/http/adapter_helper/gun.ex
  43. +2
    -2
      lib/pleroma/http/web_push.ex
  44. +6
    -0
      lib/pleroma/maps.ex
  45. +1
    -1
      lib/pleroma/object.ex
  46. +8
    -2
      lib/pleroma/object/fetcher.ex
  47. +1
    -1
      lib/pleroma/reverse_proxy.ex
  48. +0
    -18
      lib/pleroma/reverse_proxy/client.ex
  49. +29
    -0
      lib/pleroma/reverse_proxy/client/wrapper.ex
  50. +14
    -4
      lib/pleroma/upload.ex
  51. +45
    -0
      lib/pleroma/upload/filter/analyze_metadata.ex
  52. +2
    -2
      lib/pleroma/uploaders/uploader.ex
  53. +4
    -4
      lib/pleroma/user.ex
  54. +4
    -18
      lib/pleroma/web.ex
  55. +1
    -1
      lib/pleroma/web/activity_pub/activity_pub.ex
  56. +1
    -1
      lib/pleroma/web/activity_pub/activity_pub/persisting.ex
  57. +2
    -6
      lib/pleroma/web/activity_pub/activity_pub/streaming.ex
  58. +1
    -1
      lib/pleroma/web/activity_pub/builder.ex
  59. +2
    -2
      lib/pleroma/web/activity_pub/mrf/no_empty_policy.ex
  60. +23
    -1
      lib/pleroma/web/activity_pub/mrf/simple_policy.ex
  61. +4
    -3
      lib/pleroma/web/activity_pub/object_validator.ex
  62. +1
    -1
      lib/pleroma/web/activity_pub/object_validators/announce_validator.ex
  63. +7
    -0
      lib/pleroma/web/activity_pub/object_validators/answer_validator.ex
  64. +24
    -8
      lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex
  65. +4
    -2
      lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
  66. +1
    -2
      lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex
  67. +35
    -6
      lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
  68. +1
    -0
      lib/pleroma/web/activity_pub/object_validators/common_validations.ex
  69. +41
    -26
      lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex
  70. +0
    -29
      lib/pleroma/web/activity_pub/object_validators/create_note_validator.ex
  71. +2
    -2
      lib/pleroma/web/activity_pub/object_validators/event_validator.ex
  72. +2
    -2
      lib/pleroma/web/activity_pub/object_validators/question_validator.ex
  73. +13
    -13
      lib/pleroma/web/activity_pub/pipeline.ex
  74. +1
    -1
      lib/pleroma/web/activity_pub/publisher.ex
  75. +14
    -1
      lib/pleroma/web/activity_pub/side_effects.ex
  76. +53
    -54
      lib/pleroma/web/activity_pub/transmogrifier.ex
  77. +9
    -5
      lib/pleroma/web/activity_pub/utils.ex
  78. +2
    -1
      lib/pleroma/web/activity_pub/views/user_view.ex
  79. +3
    -3
      lib/pleroma/web/activity_pub/visibility.ex
  80. +0
    -1
      lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex
  81. +10
    -0
      lib/pleroma/web/admin_api/views/o_auth_app_view.ex
  82. +1
    -0
      lib/pleroma/web/api_spec/operations/media_operation.ex
  83. +2
    -1
      lib/pleroma/web/api_spec/operations/timeline_operation.ex
  84. +219
    -0
      lib/pleroma/web/api_spec/operations/twitter_util_operation.ex
  85. +1
    -0
      lib/pleroma/web/api_spec/operations/user_import_operation.ex
  86. +2
    -2
      lib/pleroma/web/channels/user_socket.ex
  87. +1
    -1
      lib/pleroma/web/common_api/utils.ex
  88. +1
    -1
      lib/pleroma/web/endpoint.ex
  89. +5
    -0
      lib/pleroma/web/federator.ex
  90. +2
    -2
      lib/pleroma/web/feed/feed_view.ex
  91. +1
    -1
      lib/pleroma/web/feed/user_controller.ex
  92. +2
    -2
      lib/pleroma/web/mastodon_api/controllers/auth_controller.ex
  93. +0
    -1
      lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex
  94. +0
    -1
      lib/pleroma/web/mastodon_api/controllers/media_controller.ex
  95. +2
    -2
      lib/pleroma/web/mastodon_api/controllers/search_controller.ex
  96. +0
    -2
      lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
  97. +11
    -0
      lib/pleroma/web/mastodon_api/views/account_view.ex
  98. +2
    -2
      lib/pleroma/web/mastodon_api/views/custom_emoji_view.ex
  99. +10
    -0
      lib/pleroma/web/mastodon_api/views/follow_request_view.ex
  100. +10
    -5
      lib/pleroma/web/mastodon_api/views/instance_view.ex

+ 2
- 1
.gitignore Dosyayı Görüntüle

@@ -28,6 +28,7 @@ erl_crash.dump
# variables. # variables.
/config/*.secret.exs /config/*.secret.exs
/config/generated_config.exs /config/generated_config.exs
/config/runtime.exs
/config/*.env /config/*.env




@@ -56,4 +57,4 @@ pleroma.iml


# Editor temp files # Editor temp files
/*~ /*~
/*#
/*#

+ 29
- 0
.gitlab-ci.yml Dosyayı Görüntüle

@@ -37,11 +37,20 @@ after_script:


build: build:
stage: build stage: build
only:
changes:
- "**/*.ex"
- "**/*.exs"
- "mix.lock"
script: script:
- mix compile --force - mix compile --force


spec-build: spec-build:
stage: test stage: test
only:
changes:
- "lib/pleroma/web/api_spec/**/*.ex"
- "lib/pleroma/web/api_spec.ex"
artifacts: artifacts:
paths: paths:
- spec.json - spec.json
@@ -64,6 +73,11 @@ benchmark:


unit-testing: unit-testing:
stage: test stage: test
only:
changes:
- "**/*.ex"
- "**/*.exs"
- "mix.lock"
retry: 2 retry: 2
cache: &testing_cache_policy cache: &testing_cache_policy
<<: *global_cache_policy <<: *global_cache_policy
@@ -97,6 +111,11 @@ unit-testing:


unit-testing-rum: unit-testing-rum:
stage: test stage: test
only:
changes:
- "**/*.ex"
- "**/*.exs"
- "mix.lock"
retry: 2 retry: 2
cache: *testing_cache_policy cache: *testing_cache_policy
services: services:
@@ -115,12 +134,22 @@ unit-testing-rum:


lint: lint:
stage: test stage: test
only:
changes:
- "**/*.ex"
- "**/*.exs"
- "mix.lock"
cache: *testing_cache_policy cache: *testing_cache_policy
script: script:
- mix format --check-formatted - mix format --check-formatted


analysis: analysis:
stage: test stage: test
only:
changes:
- "**/*.ex"
- "**/*.exs"
- "mix.lock"
cache: *testing_cache_policy cache: *testing_cache_policy
script: script:
- mix credo --strict --only=warnings,todo,fixme,consistency,readability - mix credo --strict --only=warnings,todo,fixme,consistency,readability


+ 8
- 0
CHANGELOG.md Dosyayı Görüntüle

@@ -8,16 +8,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).


### Changed ### Changed


- **Breaking:** Configuration: `:chat, enabled` moved to `:shout, enabled` and `:instance, chat_limit` moved to `:shout, limit`
- Support for Erlang/OTP 24
- The `application` metadata returned with statuses is no longer hardcoded. Apps that want to display these details will now have valid data for new posts after this change. - The `application` metadata returned with statuses is no longer hardcoded. Apps that want to display these details will now have valid data for new posts after this change.
- HTTPSecurityPlug now sends a response header to opt out of Google's FLoC (Federated Learning of Cohorts) targeted advertising. - HTTPSecurityPlug now sends a response header to opt out of Google's FLoC (Federated Learning of Cohorts) targeted advertising.
- Email address is now returned if requesting user is the owner of the user account so it can be exposed in client and FE user settings UIs.


### Added ### Added


- MRF (`FollowBotPolicy`): New MRF Policy which makes a designated local Bot account attempt to follow all users in public Notes received by your instance. Users who require approving follower requests or have #nobot in their profile are excluded. - MRF (`FollowBotPolicy`): New MRF Policy which makes a designated local Bot account attempt to follow all users in public Notes received by your instance. Users who require approving follower requests or have #nobot in their profile are excluded.
- Return OAuth token `id` (primary key) in POST `/oauth/token`. - Return OAuth token `id` (primary key) in POST `/oauth/token`.
- `AnalyzeMetadata` upload filter for extracting attachment dimensions and generating blurhashes.
- Attachment dimensions and blurhashes are federated when available.
- Pinned posts federation


### Fixed ### Fixed
- Don't crash so hard when email settings are invalid. - Don't crash so hard when email settings are invalid.
- Checking activated Upload Filters for required commands.
- Mix task `pleroma.database prune_objects` - Mix task `pleroma.database prune_objects`


## Unreleased (Patch) ## Unreleased (Patch)
@@ -29,6 +36,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Applying ConcurrentLimiter settings via AdminAPI - Applying ConcurrentLimiter settings via AdminAPI
- User login failures if their `notification_settings` were in a NULL state. - User login failures if their `notification_settings` were in a NULL state.
- Mix task `pleroma.user delete_activities` query transaction timeout is now :infinity - Mix task `pleroma.user delete_activities` query transaction timeout is now :infinity
- MRF (`SimplePolicy`): Embedded objects are now checked. If any embedded object would be rejected, its parent is rejected. This fixes Announces leaking posts from blocked domains.
- Fixed some Markdown issues, including trailing slash in links. - Fixed some Markdown issues, including trailing slash in links.


## [2.3.0] - 2020-03-01 ## [2.3.0] - 2020-03-01


+ 1
- 1
Dockerfile Dosyayı Görüntüle

@@ -33,7 +33,7 @@ ARG DATA=/var/lib/pleroma


RUN echo "http://nl.alpinelinux.org/alpine/latest-stable/community" >> /etc/apk/repositories &&\ RUN echo "http://nl.alpinelinux.org/alpine/latest-stable/community" >> /etc/apk/repositories &&\
apk update &&\ apk update &&\
apk add exiftool imagemagick libmagic ncurses postgresql-client &&\
apk add exiftool ffmpeg imagemagick libmagic ncurses postgresql-client &&\
adduser --system --shell /bin/false --home ${HOME} pleroma &&\ adduser --system --shell /bin/false --home ${HOME} pleroma &&\
mkdir -p ${DATA}/uploads &&\ mkdir -p ${DATA}/uploads &&\
mkdir -p ${DATA}/static &&\ mkdir -p ${DATA}/static &&\


+ 2
- 2
README.md Dosyayı Görüntüle

@@ -50,5 +50,5 @@ If you are not developing Pleroma, it is better to use the OTP release, which co
- Latest Git revision: <https://docs-develop.pleroma.social> - Latest Git revision: <https://docs-develop.pleroma.social>


## Community Channels ## Community Channels
* IRC: **#pleroma** and **#pleroma-dev** on freenode, webchat is available at <https://irc.pleroma.social>
* Matrix: <https://matrix.to/#/#freenode_#pleroma:matrix.org> and <https://matrix.to/#/#freenode_#pleroma-dev:matrix.org>
* IRC: **#pleroma** and **#pleroma-dev** on libera.chat, webchat is available at <https://irc.pleroma.social>
* Matrix: [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) and [#pleroma-dev:libera.chat](https://matrix.to/#/#pleroma-dev:libera.chat)

+ 1
- 1
benchmarks/load_testing/activities.ex Dosyayı Görüntüle

@@ -299,7 +299,7 @@ defmodule Pleroma.LoadTesting.Activities do
"url" => [ "url" => [
%{ %{
"href" => "href" =>
"#{Pleroma.Web.base_url()}/media/b1b873552422a07bf53af01f3c231c841db4dfc42c35efde681abaf0f2a4eab7.jpg",
"#{Pleroma.Web.Endpoint.url()}/media/b1b873552422a07bf53af01f3c231c841db4dfc42c35efde681abaf0f2a4eab7.jpg",
"mediaType" => "image/jpeg", "mediaType" => "image/jpeg",
"type" => "Link" "type" => "Link"
} }


+ 1
- 1
config/benchmark.exs Dosyayı Görüntüle

@@ -1,4 +1,4 @@
use Mix.Config
import Config


# We don't run a server during test. If one is required, # We don't run a server during test. If one is required,
# you can enable the server option below. # you can enable the server option below.


+ 4
- 3
config/config.exs Dosyayı Görüntüle

@@ -41,7 +41,7 @@
# #
# This configuration file is loaded before any dependency and # This configuration file is loaded before any dependency and
# is restricted to this project. # is restricted to this project.
use Mix.Config
import Config


# General application configuration # General application configuration
config :pleroma, ecto_repos: [Pleroma.Repo] config :pleroma, ecto_repos: [Pleroma.Repo]
@@ -190,7 +190,6 @@ config :pleroma, :instance,
instance_thumbnail: "/instance/thumbnail.jpeg", instance_thumbnail: "/instance/thumbnail.jpeg",
limit: 5_000, limit: 5_000,
description_limit: 5_000, description_limit: 5_000,
chat_limit: 5_000,
remote_limit: 100_000, remote_limit: 100_000,
upload_limit: 16_000_000, upload_limit: 16_000_000,
avatar_upload_limit: 2_000_000, avatar_upload_limit: 2_000_000,
@@ -457,7 +456,9 @@ config :pleroma, :media_preview_proxy,
image_quality: 85, image_quality: 85,
min_content_length: 100 * 1024 min_content_length: 100 * 1024


config :pleroma, :chat, enabled: true
config :pleroma, :shout,
enabled: true,
limit: 5_000


config :phoenix, :format_encoders, json: Jason config :phoenix, :format_encoders, json: Jason




+ 15
- 20
config/description.exs Dosyayı Görüntüle

@@ -1,4 +1,4 @@
use Mix.Config
import Config


websocket_config = [ websocket_config = [
path: "/websocket", path: "/websocket",
@@ -545,14 +545,6 @@ config :pleroma, :config_description, [
] ]
}, },
%{ %{
key: :chat_limit,
type: :integer,
description: "Character limit of the instance chat messages",
suggestions: [
5_000
]
},
%{
key: :remote_limit, key: :remote_limit,
type: :integer, type: :integer,
description: "Hard character limit beyond which remote posts will be dropped", description: "Hard character limit beyond which remote posts will be dropped",
@@ -682,7 +674,8 @@ config :pleroma, :config_description, [
%{ %{
key: :allow_relay, key: :allow_relay,
type: :boolean, type: :boolean,
description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance"
description:
"Permits remote instances to subscribe to all public posts of your instance. (Important!) This may increase the visibility of your instance."
}, },
%{ %{
key: :public, key: :public,
@@ -1182,7 +1175,6 @@ config :pleroma, :config_description, [
alwaysShowSubjectInput: true, alwaysShowSubjectInput: true,
background: "/static/aurora_borealis.jpg", background: "/static/aurora_borealis.jpg",
collapseMessageWithSubject: false, collapseMessageWithSubject: false,
disableChat: false,
greentext: false, greentext: false,
hideFilteredStatuses: false, hideFilteredStatuses: false,
hideMutedPosts: false, hideMutedPosts: false,
@@ -1230,12 +1222,6 @@ config :pleroma, :config_description, [
"When a message has a subject (aka Content Warning), collapse it by default" "When a message has a subject (aka Content Warning), collapse it by default"
}, },
%{ %{
key: :disableChat,
label: "PleromaFE Chat",
type: :boolean,
description: "Disables PleromaFE Chat component"
},
%{
key: :greentext, key: :greentext,
label: "Greentext", label: "Greentext",
type: :boolean, type: :boolean,
@@ -2652,13 +2638,22 @@ config :pleroma, :config_description, [
}, },
%{ %{
group: :pleroma, group: :pleroma,
key: :chat,
key: :shout,
type: :group, type: :group,
description: "Pleroma chat settings",
description: "Pleroma shout settings",
children: [ children: [
%{ %{
key: :enabled, key: :enabled,
type: :boolean
type: :boolean,
description: "Enables the backend Shoutbox chat feature."
},
%{
key: :limit,
type: :integer,
description: "Shout message character limit.",
suggestions: [
5_000
]
} }
] ]
}, },


+ 5
- 1
config/dev.exs Dosyayı Görüntüle

@@ -1,4 +1,4 @@
use Mix.Config
import Config


# For development, we disable any cache and enable # For development, we disable any cache and enable
# debugging and code reloading. # debugging and code reloading.
@@ -54,6 +54,10 @@ config :pleroma, Pleroma.Repo,


config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true


# Reduce recompilation time
# https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects
config :phoenix, :plug_init_mode, :runtime

if File.exists?("./config/dev.secret.exs") do if File.exists?("./config/dev.secret.exs") do
import_config "dev.secret.exs" import_config "dev.secret.exs"
else else


+ 1
- 1
config/dokku.exs Dosyayı Görüntüle

@@ -1,4 +1,4 @@
use Mix.Config
import Config


config :pleroma, Pleroma.Web.Endpoint, config :pleroma, Pleroma.Web.Endpoint,
http: [ http: [


+ 7
- 2
config/prod.exs Dosyayı Görüntüle

@@ -1,4 +1,4 @@
use Mix.Config
import Config


# For production, we often load configuration from external # For production, we often load configuration from external
# sources, such as your system environment. For this reason, # sources, such as your system environment. For this reason,
@@ -63,7 +63,12 @@ config :logger, :ex_syslogger, level: :info


# Finally import the config/prod.secret.exs # Finally import the config/prod.secret.exs
# which should be versioned separately. # which should be versioned separately.
import_config "prod.secret.exs"
if File.exists?("./config/prod.secret.exs") do
import_config "prod.secret.exs"
else
"`config/prod.secret.exs` not found. You may want to create one by running `mix pleroma.instance gen`"
|> IO.warn([])
end


if File.exists?("./config/prod.exported_from_db.secret.exs"), if File.exists?("./config/prod.exported_from_db.secret.exs"),
do: import_config("prod.exported_from_db.secret.exs") do: import_config("prod.exported_from_db.secret.exs")

+ 5
- 1
config/test.exs Dosyayı Görüntüle

@@ -1,4 +1,4 @@
use Mix.Config
import Config


# We don't run a server during test. If one is required, # We don't run a server during test. If one is required,
# you can enable the server option below. # you can enable the server option below.
@@ -133,6 +133,10 @@ config :pleroma, :side_effects,
ap_streamer: Pleroma.Web.ActivityPub.ActivityPubMock, ap_streamer: Pleroma.Web.ActivityPub.ActivityPubMock,
logger: Pleroma.LoggerMock logger: Pleroma.LoggerMock


# Reduce recompilation time
# https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects
config :phoenix, :plug_init_mode, :runtime

if File.exists?("./config/test.secret.exs") do if File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs" import_config "test.secret.exs"
else else


+ 4
- 4
docs/configuration/cheatsheet.md Dosyayı Görüntüle

@@ -8,9 +8,10 @@ For from source installations Pleroma configuration works by first importing the


To add configuration to your config file, you can copy it from the base config. The latest version of it can be viewed [here](https://git.pleroma.social/pleroma/pleroma/blob/develop/config/config.exs). You can also use this file if you don't know how an option is supposed to be formatted. To add configuration to your config file, you can copy it from the base config. The latest version of it can be viewed [here](https://git.pleroma.social/pleroma/pleroma/blob/develop/config/config.exs). You can also use this file if you don't know how an option is supposed to be formatted.


## :chat
## :shout


* `enabled` - Enables the backend chat. Defaults to `true`.
* `enabled` - Enables the backend Shoutbox chat feature. Defaults to `true`.
* `limit` - Shout character limit. Defaults to `5_000`


## :instance ## :instance
* `name`: The instance’s name. * `name`: The instance’s name.
@@ -19,7 +20,6 @@ To add configuration to your config file, you can copy it from the base config.
* `description`: The instance’s description, can be seen in nodeinfo and ``/api/v1/instance``. * `description`: The instance’s description, can be seen in nodeinfo and ``/api/v1/instance``.
* `limit`: Posts character limit (CW/Subject included in the counter). * `limit`: Posts character limit (CW/Subject included in the counter).
* `description_limit`: The character limit for image descriptions. * `description_limit`: The character limit for image descriptions.
* `chat_limit`: Character limit of the instance chat messages.
* `remote_limit`: Hard character limit beyond which remote posts will be dropped. * `remote_limit`: Hard character limit beyond which remote posts will be dropped.
* `upload_limit`: File size limit of uploads (except for avatar, background, banner). * `upload_limit`: File size limit of uploads (except for avatar, background, banner).
* `avatar_upload_limit`: File size limit of user’s profile avatars. * `avatar_upload_limit`: File size limit of user’s profile avatars.
@@ -37,7 +37,7 @@ To add configuration to your config file, you can copy it from the base config.
* `federating`: Enable federation with other instances. * `federating`: Enable federation with other instances.
* `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes. * `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes.
* `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it. * `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it.
* `allow_relay`: Enable Pleroma’s Relay, which makes it possible to follow a whole instance.
* `allow_relay`: Permits remote instances to subscribe to all public posts of your instance. This may increase the visibility of your instance.
* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note that there is a dependent setting restricting or allowing unauthenticated access to specific resources, see `restrict_unauthenticated` for more details. * `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note that there is a dependent setting restricting or allowing unauthenticated access to specific resources, see `restrict_unauthenticated` for more details.
* `quarantined_instances`: List of ActivityPub instances where private (DMs, followers-only) activities will not be send. * `quarantined_instances`: List of ActivityPub instances where private (DMs, followers-only) activities will not be send.
* `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML). * `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML).


+ 1
- 1
docs/development/API/pleroma_api.md Dosyayı Görüntüle

@@ -300,7 +300,7 @@ See [Admin-API](admin_api.md)
* Note: Behaves exactly the same as `POST /api/v1/upload`. * Note: Behaves exactly the same as `POST /api/v1/upload`.
Can only accept images - any attempt to upload non-image files will be met with `HTTP 415 Unsupported Media Type`. Can only accept images - any attempt to upload non-image files will be met with `HTTP 415 Unsupported Media Type`.


## `/api/v1/pleroma/notification_settings`
## `/api/pleroma/notification_settings`
### Updates user notification settings ### Updates user notification settings
* Method `PUT` * Method `PUT`
* Authentication: required * Authentication: required


+ 2
- 2
docs/installation/alpine_linux_en.md Dosyayı Görüntüle

@@ -117,7 +117,7 @@ cd /opt/pleroma
sudo -Hu pleroma mix deps.get sudo -Hu pleroma mix deps.get
``` ```


* Generate the configuration: `sudo -Hu pleroma mix pleroma.instance gen`
* Generate the configuration: `sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
* Answer with `yes` if it asks you to install `rebar3`. * Answer with `yes` if it asks you to install `rebar3`.
* This may take some time, because parts of pleroma get compiled first. * 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`. * After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`.
@@ -240,4 +240,4 @@ sudo -Hu pleroma MIX_ENV=prod mix pleroma.user new <username> <your@emailaddress


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC.

+ 2
- 2
docs/installation/arch_linux_en.md Dosyayı Görüntüle

@@ -92,7 +92,7 @@ cd /opt/pleroma
sudo -Hu pleroma mix deps.get sudo -Hu pleroma mix deps.get
``` ```


* Generate the configuration: `sudo -Hu pleroma mix pleroma.instance gen`
* Generate the configuration: `sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
* Answer with `yes` if it asks you to install `rebar3`. * Answer with `yes` if it asks you to install `rebar3`.
* This may take some time, because parts of pleroma get compiled first. * 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`. * After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`.
@@ -215,4 +215,4 @@ sudo -Hu pleroma MIX_ENV=prod mix pleroma.user new <username> <your@emailaddress


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC.

+ 2
- 2
docs/installation/debian_based_en.md Dosyayı Görüntüle

@@ -90,7 +90,7 @@ cd /opt/pleroma
sudo -Hu pleroma mix deps.get sudo -Hu pleroma mix deps.get
``` ```


* Generate the configuration: `sudo -Hu pleroma mix pleroma.instance gen`
* Generate the configuration: `sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
* Answer with `yes` if it asks you to install `rebar3`. * Answer with `yes` if it asks you to install `rebar3`.
* This may take some time, because parts of pleroma get compiled first. * 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`. * After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`.
@@ -202,4 +202,4 @@ sudo -Hu pleroma MIX_ENV=prod mix pleroma.user new <username> <your@emailaddress


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC.

+ 4
- 4
docs/installation/debian_based_jp.md Dosyayı Görüntüle

@@ -89,7 +89,7 @@ sudo -Hu pleroma mix deps.get


* コンフィギュレーションを生成します。 * コンフィギュレーションを生成します。
``` ```
sudo -Hu pleroma mix pleroma.instance gen
sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen
``` ```
* rebar3をインストールしてもよいか聞かれたら、yesを入力してください。 * rebar3をインストールしてもよいか聞かれたら、yesを入力してください。
* このときにpleromaの一部がコンパイルされるため、この処理には時間がかかります。 * このときにpleromaの一部がコンパイルされるため、この処理には時間がかかります。
@@ -103,7 +103,7 @@ sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}


* 先程のコマンドで、すでに `config/setup_db.psql` というファイルが作られています。このファイルをもとに、データベースを作成します。 * 先程のコマンドで、すでに `config/setup_db.psql` というファイルが作られています。このファイルをもとに、データベースを作成します。
``` ```
sudo -Hu pleroma mix pleroma.instance gen
sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen
``` ```


* そして、データベースのマイグレーションを実行します。 * そして、データベースのマイグレーションを実行します。
@@ -191,5 +191,5 @@ sudo -Hu pleroma MIX_ENV=prod mix pleroma.user new <username> <your@emailaddress


インストールについて質問がある、もしくは、うまくいかないときは、以下のところで質問できます。 インストールについて質問がある、もしくは、うまくいかないときは、以下のところで質問できます。


* [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org)
* **Freenode** の **#pleroma** IRCチャンネル
* [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat)
* **libera.chat** の **#pleroma** IRCチャンネル

+ 4
- 4
docs/installation/freebsd_en.md Dosyayı Görüntüle

@@ -1,8 +1,8 @@
# Installing on FreeBSD
# Installing on FreeBSD


This document was written for FreeBSD 12.1, but should be work on future releases. This document was written for FreeBSD 12.1, but should be work on future releases.


## Required software
## Required software


This assumes the target system has `pkg(8)`. This assumes the target system has `pkg(8)`.


@@ -54,7 +54,7 @@ Configure Pleroma. Note that you need a domain name at this point:
``` ```
$ cd /home/pleroma/pleroma $ cd /home/pleroma/pleroma
$ mix deps.get # Enter "y" when asked to install Hex $ mix deps.get # Enter "y" when asked to install Hex
$ mix pleroma.instance gen # You will be asked a few questions here.
$ MIX_ENV=prod mix pleroma.instance gen # You will be asked a few questions here.
$ cp config/generated_config.exs config/prod.secret.exs $ cp config/generated_config.exs config/prod.secret.exs
``` ```


@@ -213,4 +213,4 @@ incorrect timestamps. You should have ntpd running.


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC.

+ 6
- 6
docs/installation/gentoo_en.md Dosyayı Görüntüle

@@ -54,7 +54,7 @@ Gentoo quite pointedly does not come with a cron daemon installed, and as such i
# emerge --ask dev-db/postgresql dev-lang/elixir dev-vcs/git www-servers/nginx app-crypt/certbot app-crypt/certbot-nginx dev-util/cmake sys-apps/file # emerge --ask dev-db/postgresql dev-lang/elixir dev-vcs/git www-servers/nginx app-crypt/certbot app-crypt/certbot-nginx dev-util/cmake sys-apps/file
``` ```


If you would not like to install the optional packages, remove them from this line.
If you would not like to install the optional packages, remove them from this line.


If you're running this from a low-powered virtual machine, it should work though it will take some time. There were no issues on a VPS with a single core and 1GB of RAM; if you are using an even more limited device and run into issues, you can try creating a swapfile or use a more powerful machine running Gentoo to [cross build](https://wiki.gentoo.org/wiki/Cross_build_environment). If you have a wait ahead of you, now would be a good time to take a break, strech a bit, refresh your beverage of choice and/or get a snack, and reply to Arch users' posts with "I use Gentoo btw" as we do. If you're running this from a low-powered virtual machine, it should work though it will take some time. There were no issues on a VPS with a single core and 1GB of RAM; if you are using an even more limited device and run into issues, you can try creating a swapfile or use a more powerful machine running Gentoo to [cross build](https://wiki.gentoo.org/wiki/Cross_build_environment). If you have a wait ahead of you, now would be a good time to take a break, strech a bit, refresh your beverage of choice and/or get a snack, and reply to Arch users' posts with "I use Gentoo btw" as we do.


@@ -79,12 +79,12 @@ The output from emerging postgresql should give you a command for initializing t
``` ```


* Start postgres and enable the system service * Start postgres and enable the system service
```shell ```shell
# /etc/init.d/postgresql-11 start # /etc/init.d/postgresql-11 start
# rc-update add postgresql-11 default # rc-update add postgresql-11 default
``` ```
### A note on licenses, the AGPL, and deployment procedures ### A note on licenses, the AGPL, and deployment procedures


If you do not plan to make any modifications to your Pleroma instance, cloning directly from the main repo will get you what you need. However, if you plan on doing any contributions to upstream development, making changes or modifications to your instance, making custom themes, or want to play around--and let's be honest here, if you're using Gentoo that is most likely you--you will save yourself a lot of headache later if you take the time right now to fork the Pleroma repo and use that in the following section. If you do not plan to make any modifications to your Pleroma instance, cloning directly from the main repo will get you what you need. However, if you plan on doing any contributions to upstream development, making changes or modifications to your instance, making custom themes, or want to play around--and let's be honest here, if you're using Gentoo that is most likely you--you will save yourself a lot of headache later if you take the time right now to fork the Pleroma repo and use that in the following section.
@@ -135,7 +135,7 @@ pleroma$ mix deps.get
* Generate the configuration: * Generate the configuration:


```shell ```shell
pleroma$ mix pleroma.instance gen
pleroma$ MIX_ENV=prod mix pleroma.instance gen
``` ```


* Answer with `yes` if it asks you to install `rebar3`. * Answer with `yes` if it asks you to install `rebar3`.
@@ -241,7 +241,7 @@ First, ensure that the command you will be installing into your crontab works.
# /usr/bin/certbot renew --nginx # /usr/bin/certbot renew --nginx
``` ```


Assuming not much time has passed since you got certbot working a few steps ago, you should get a message for all domains you installed certificates for saying `Cert not yet due for renewal`.
Assuming not much time has passed since you got certbot working a few steps ago, you should get a message for all domains you installed certificates for saying `Cert not yet due for renewal`.


Now, run crontab as a superuser with `crontab -e` or `sudo crontab -e` as appropriate, and add the following line to your cron: Now, run crontab as a superuser with `crontab -e` or `sudo crontab -e` as appropriate, and add the following line to your cron:


@@ -298,4 +298,4 @@ If you opted to allow sudo for the `pleroma` user but would like to remove the a


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC.

+ 3
- 5
docs/installation/netbsd_en.md Dosyayı Görüntüle

@@ -1,6 +1,6 @@
# Installing on NetBSD # Installing on NetBSD


## Required software
## Required software


pkgin should have been installed by the NetBSD installer if you selected pkgin should have been installed by the NetBSD installer if you selected
the right options. If it isn't installed, install it using pkg_add. the right options. If it isn't installed, install it using pkg_add.
@@ -71,7 +71,7 @@ Configure Pleroma. Note that you need a domain name at this point:
``` ```
$ cd /home/pleroma/pleroma $ cd /home/pleroma/pleroma
$ mix deps.get $ mix deps.get
$ mix pleroma.instance gen # You will be asked a few questions here.
$ MIX_ENV=prod mix pleroma.instance gen # You will be asked a few questions here.
``` ```


Since Postgres is configured, we can now initialize the database. There should Since Postgres is configured, we can now initialize the database. There should
@@ -193,8 +193,6 @@ Run `# /etc/rc.d/pleroma start` to start Pleroma.


Restart nginx with `# /etc/rc.d/nginx restart` and you should be up and running. Restart nginx with `# /etc/rc.d/nginx restart` and you should be up and running.


If you need further help, contact niaa on freenode.

Make sure your time is in sync, or other instances will receive your posts with Make sure your time is in sync, or other instances will receive your posts with
incorrect timestamps. You should have ntpd running. incorrect timestamps. You should have ntpd running.


@@ -208,4 +206,4 @@ incorrect timestamps. You should have ntpd running.


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC.

+ 2
- 2
docs/installation/openbsd_en.md Dosyayı Görüntüle

@@ -239,7 +239,7 @@ Enter a shell as \_pleroma (as root `su _pleroma -`) and enter pleroma's install
Then follow the main installation guide: Then follow the main installation guide:


* run `mix deps.get` * run `mix deps.get`
* run `mix pleroma.instance gen` and enter your instance's information when asked
* run `MIX_ENV=prod mix pleroma.instance gen` and enter your instance's information when asked
* copy config/generated\_config.exs to config/prod.secret.exs. The default values should be sufficient but you should edit it and check that everything seems OK. * copy config/generated\_config.exs to config/prod.secret.exs. The default values should be sufficient but you should edit it and check that everything seems OK.
* exit your current shell back to a root one and run `psql -U postgres -f /home/_pleroma/pleroma/config/setup_db.psql` to setup the database. * exit your current shell back to a root one and run `psql -U postgres -f /home/_pleroma/pleroma/config/setup_db.psql` to setup the database.
* return to a \_pleroma shell into pleroma's installation directory (`su _pleroma -;cd ~/pleroma`) and run `MIX_ENV=prod mix ecto.migrate` * return to a \_pleroma shell into pleroma's installation directory (`su _pleroma -;cd ~/pleroma`) and run `MIX_ENV=prod mix ecto.migrate`
@@ -264,4 +264,4 @@ LC_ALL=en_US.UTF-8 MIX_ENV=prod mix pleroma.user new <username> <your@emailaddre


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC.

+ 2
- 2
docs/installation/openbsd_fi.md Dosyayı Görüntüle

@@ -10,8 +10,8 @@ suositeltavaa tehdä komennon `doas` avulla, katso `doas (1)` ja `doas.conf (5)`
Tästä eteenpäin oletuksena on, että domain "esimerkki.com" osoittaa Tästä eteenpäin oletuksena on, että domain "esimerkki.com" osoittaa
serverin IP-osoitteeseen. serverin IP-osoitteeseen.


Jos asennuksen kanssa on ongelmia, IRC-kanava #pleroma Freenodessa tai
Matrix-kanava #freenode_#pleroma:matrix.org ovat hyviä paikkoja löytää apua
Jos asennuksen kanssa on ongelmia, IRC-kanava #pleroma Libera.chat tai
Matrix-kanava #pleroma:libera.chat ovat hyviä paikkoja löytää apua
(englanniksi), `/msg eal kukkuu` jos haluat välttämättä puhua härmää. (englanniksi), `/msg eal kukkuu` jos haluat välttämättä puhua härmää.


Asenna tarvittava ohjelmisto: Asenna tarvittava ohjelmisto:


+ 2
- 2
docs/installation/otp_en.md Dosyayı Görüntüle

@@ -232,7 +232,7 @@ At this point if you open your (sub)domain in a browser you should see a 502 err


If everything worked, you should see Pleroma-FE when visiting your domain. If that didn't happen, try reviewing the installation steps, starting Pleroma in the foreground and seeing if there are any errrors. If everything worked, you should see Pleroma-FE when visiting your domain. If that didn't happen, try reviewing the installation steps, starting Pleroma in the foreground and seeing if there are any errrors.


Still doesn't work? Feel free to contact us on [#pleroma on freenode](https://irc.pleroma.social) or via matrix at <https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org>, you can also [file an issue on our Gitlab](https://git.pleroma.social/pleroma/pleroma-support/issues/new)
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC, you can also [file an issue on our Gitlab](https://git.pleroma.social/pleroma/pleroma-support/issues/new).


## Post installation ## Post installation


@@ -301,4 +301,4 @@ This will create an account withe the username of 'joeuser' with the email addre


## Questions ## Questions


Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:libera.chat](https://matrix.to/#/#pleroma:libera.chat) via Matrix or **#pleroma** on **libera.chat** via IRC, you can also [file an issue on our Gitlab](https://git.pleroma.social/pleroma/pleroma-support/issues/new).

+ 45
- 0
lib/pleroma/activity/html.ex Dosyayı Görüntüle

@@ -0,0 +1,45 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Activity.HTML do
alias Pleroma.HTML
alias Pleroma.Object

@cachex Pleroma.Config.get([:cachex, :provider], Cachex)

def get_cached_scrubbed_html_for_activity(
content,
scrubbers,
activity,
key \\ "",
callback \\ fn x -> x end
) do
key = "#{key}#{generate_scrubber_signature(scrubbers)}|#{activity.id}"

@cachex.fetch!(:scrubber_cache, key, fn _key ->
object = Object.normalize(activity, fetch: false)
HTML.ensure_scrubbed_html(content, scrubbers, object.data["fake"] || false, callback)
end)
end

def get_cached_stripped_html_for_activity(content, activity, key) do
get_cached_scrubbed_html_for_activity(
content,
FastSanitize.Sanitizer.StripTags,
activity,
key,
&HtmlEntities.decode/1
)
end

defp generate_scrubber_signature(scrubber) when is_atom(scrubber) do
generate_scrubber_signature([scrubber])
end

defp generate_scrubber_signature(scrubbers) do
Enum.reduce(scrubbers, "", fn scrubber, signature ->
"#{signature}#{to_string(scrubber)}"
end)
end
end

+ 6
- 6
lib/pleroma/application.ex Dosyayı Görüntüle

@@ -25,7 +25,7 @@ defmodule Pleroma.Application do
if Process.whereis(Pleroma.Web.Endpoint) do if Process.whereis(Pleroma.Web.Endpoint) do
case Config.get([:http, :user_agent], :default) do case Config.get([:http, :user_agent], :default) do
:default -> :default ->
info = "#{Pleroma.Web.base_url()} <#{Config.get([:instance, :email], "")}>"
info = "#{Pleroma.Web.Endpoint.url()} <#{Config.get([:instance, :email], "")}>"
named_version() <> "; " <> info named_version() <> "; " <> info


custom -> custom ->
@@ -102,7 +102,7 @@ defmodule Pleroma.Application do
] ++ ] ++
task_children(@mix_env) ++ task_children(@mix_env) ++
dont_run_in_test(@mix_env) ++ dont_run_in_test(@mix_env) ++
chat_child(chat_enabled?()) ++
shout_child(shout_enabled?()) ++
[Pleroma.Gopher.Server] [Pleroma.Gopher.Server]


# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
@@ -216,7 +216,7 @@ defmodule Pleroma.Application do
type: :worker type: :worker
} }


defp chat_enabled?, do: Config.get([:chat, :enabled])
defp shout_enabled?, do: Config.get([:shout, :enabled])


defp dont_run_in_test(env) when env in [:test, :benchmark], do: [] defp dont_run_in_test(env) when env in [:test, :benchmark], do: []


@@ -237,14 +237,14 @@ defmodule Pleroma.Application do
] ]
end end


defp chat_child(true) do
defp shout_child(true) do
[ [
Pleroma.Web.ChatChannel.ChatChannelState,
Pleroma.Web.ShoutChannel.ShoutChannelState,
{Phoenix.PubSub, [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2]} {Phoenix.PubSub, [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2]}
] ]
end end


defp chat_child(_), do: []
defp shout_child(_), do: []


defp task_children(:test) do defp task_children(:test) do
[ [


+ 5
- 3
lib/pleroma/application_requirements.ex Dosyayı Görüntüle

@@ -164,9 +164,11 @@ defmodule Pleroma.ApplicationRequirements do


defp check_system_commands!(:ok) do defp check_system_commands!(:ok) do
filter_commands_statuses = [ filter_commands_statuses = [
check_filter(Pleroma.Upload.Filters.Exiftool, "exiftool"),
check_filter(Pleroma.Upload.Filters.Mogrify, "mogrify"),
check_filter(Pleroma.Upload.Filters.Mogrifun, "mogrify")
check_filter(Pleroma.Upload.Filter.Exiftool, "exiftool"),
check_filter(Pleroma.Upload.Filter.Mogrify, "mogrify"),
check_filter(Pleroma.Upload.Filter.Mogrifun, "mogrify"),
check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "mogrify"),
check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "convert")
] ]


preview_proxy_commands_status = preview_proxy_commands_status =


+ 25
- 1
lib/pleroma/config/deprecation_warnings.ex Dosyayı Görüntüle

@@ -41,7 +41,8 @@ defmodule Pleroma.Config.DeprecationWarnings do
:ok <- check_gun_pool_options(), :ok <- check_gun_pool_options(),
:ok <- check_activity_expiration_config(), :ok <- check_activity_expiration_config(),
:ok <- check_remote_ip_plug_name(), :ok <- check_remote_ip_plug_name(),
:ok <- check_uploders_s3_public_endpoint() do
:ok <- check_uploders_s3_public_endpoint(),
:ok <- check_old_chat_shoutbox() do
:ok :ok
else else
_ -> _ ->
@@ -215,4 +216,27 @@ defmodule Pleroma.Config.DeprecationWarnings do
:ok :ok
end end
end end

@spec check_old_chat_shoutbox() :: :ok | nil
def check_old_chat_shoutbox do
instance_config = Pleroma.Config.get([:instance])
chat_config = Pleroma.Config.get([:chat]) || []

use_old_config =
Keyword.has_key?(instance_config, :chat_limit) or
Keyword.has_key?(chat_config, :enabled)

if use_old_config do
Logger.error("""
!!!DEPRECATION WARNING!!!
Your config is using the old namespace for the Shoutbox configuration. You need to convert to the new namespace. e.g.,
\n* `config :pleroma, :chat, enabled` and `config :pleroma, :instance, chat_limit` are now equal to:
\n* `config :pleroma, :shout, enabled` and `config :pleroma, :shout, limit`
""")

:error
else
:ok
end
end
end end

+ 16
- 14
lib/pleroma/config/loader.ex Dosyayı Görüntüle

@@ -3,19 +3,21 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only


defmodule Pleroma.Config.Loader do defmodule Pleroma.Config.Loader do
@reject_keys [
Pleroma.Repo,
Pleroma.Web.Endpoint,
:env,
:configurable_from_database,
:database,
:swarm
]

@reject_groups [
:postgrex,
:tesla
]
defp reject_keys,
do: [
Pleroma.Repo,
Pleroma.Web.Endpoint,
:env,
:configurable_from_database,
:database,
:swarm
]

defp reject_groups,
do: [
:postgrex,
:tesla
]


if Code.ensure_loaded?(Config.Reader) do if Code.ensure_loaded?(Config.Reader) do
@reader Config.Reader @reader Config.Reader
@@ -52,7 +54,7 @@ defmodule Pleroma.Config.Loader do
@spec filter_group(atom(), keyword()) :: keyword() @spec filter_group(atom(), keyword()) :: keyword()
def filter_group(group, configs) do def filter_group(group, configs) do
Enum.reject(configs[group], fn {key, _v} -> Enum.reject(configs[group], fn {key, _v} ->
key in @reject_keys or group in @reject_groups or
key in reject_keys() or group in reject_groups() or
(group == :phoenix and key == :serve_endpoints) (group == :phoenix and key == :serve_endpoints)
end) end)
end end


+ 21
- 19
lib/pleroma/config/transfer_task.ex Dosyayı Görüntüle

@@ -13,23 +13,25 @@ defmodule Pleroma.Config.TransferTask do


@type env() :: :test | :benchmark | :dev | :prod @type env() :: :test | :benchmark | :dev | :prod


@reboot_time_keys [
{:pleroma, :hackney_pools},
{:pleroma, :chat},
{:pleroma, Oban},
{:pleroma, :rate_limit},
{:pleroma, :markup},
{:pleroma, :streamer},
{:pleroma, :pools},
{:pleroma, :connections_pool}
]

@reboot_time_subkeys [
{:pleroma, Pleroma.Captcha, [:seconds_valid]},
{:pleroma, Pleroma.Upload, [:proxy_remote]},
{:pleroma, :instance, [:upload_limit]},
{:pleroma, :gopher, [:enabled]}
]
defp reboot_time_keys,
do: [
{:pleroma, :hackney_pools},
{:pleroma, :shout},
{:pleroma, Oban},
{:pleroma, :rate_limit},
{:pleroma, :markup},
{:pleroma, :streamer},
{:pleroma, :pools},
{:pleroma, :connections_pool}
]

defp reboot_time_subkeys,
do: [
{:pleroma, Pleroma.Captcha, [:seconds_valid]},
{:pleroma, Pleroma.Upload, [:proxy_remote]},
{:pleroma, :instance, [:upload_limit]},
{:pleroma, :gopher, [:enabled]}
]


def start_link(restart_pleroma? \\ true) do def start_link(restart_pleroma? \\ true) do
load_and_update_env([], restart_pleroma?) load_and_update_env([], restart_pleroma?)
@@ -165,12 +167,12 @@ defmodule Pleroma.Config.TransferTask do
end end


defp group_and_key_need_reboot?(group, key) do defp group_and_key_need_reboot?(group, key) do
Enum.any?(@reboot_time_keys, fn {g, k} -> g == group and k == key end)
Enum.any?(reboot_time_keys(), fn {g, k} -> g == group and k == key end)
end end


defp group_and_subkey_need_reboot?(group, key, value) do defp group_and_subkey_need_reboot?(group, key, value) do
Keyword.keyword?(value) and Keyword.keyword?(value) and
Enum.any?(@reboot_time_subkeys, fn {g, k, subkeys} ->
Enum.any?(reboot_time_subkeys(), fn {g, k, subkeys} ->
g == group and k == key and g == group and k == key and
Enum.any?(Keyword.keys(value), &(&1 in subkeys)) Enum.any?(Keyword.keys(value), &(&1 in subkeys))
end) end)


+ 0
- 2
lib/pleroma/constants.ex Dosyayı Görüntüle

@@ -27,6 +27,4 @@ defmodule Pleroma.Constants do
do: do:
~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css) ~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css)
) )

def as_local_public, do: Pleroma.Web.base_url() <> "/#Public"
end end

+ 24
- 12
lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex Dosyayı Görüntüle

@@ -13,21 +13,33 @@ defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients do
cast([object]) cast([object])
end end


def cast(object) when is_map(object) do
case ObjectID.cast(object) do
{:ok, data} -> {:ok, [data]}
_ -> :error
end
end

def cast(data) when is_list(data) do def cast(data) when is_list(data) do
data
|> Enum.reduce_while({:ok, []}, fn element, {:ok, list} ->
case ObjectID.cast(element) do
{:ok, id} ->
{:cont, {:ok, [id | list]}}

_ ->
{:halt, :error}
end
end)
data =
data
|> Enum.reduce_while([], fn element, list ->
case ObjectID.cast(element) do
{:ok, id} ->
{:cont, [id | list]}

_ ->
{:cont, list}
end
end)
|> Enum.sort()
|> Enum.uniq()

{:ok, data}
end end


def cast(_) do
:error
def cast(data) do
{:error, data}
end end


def dump(data) do def dump(data) do


+ 2
- 2
lib/pleroma/emails/admin_email.ex Dosyayı Görüntüle

@@ -73,7 +73,7 @@ defmodule Pleroma.Emails.AdminEmail do
#{comment_html} #{comment_html}
#{statuses_html} #{statuses_html}
<p> <p>
<a href="#{Pleroma.Web.base_url()}/pleroma/admin/#/reports/index">View Reports in AdminFE</a>
<a href="#{Pleroma.Web.Endpoint.url()}/pleroma/admin/#/reports/index">View Reports in AdminFE</a>
""" """


new() new()
@@ -87,7 +87,7 @@ defmodule Pleroma.Emails.AdminEmail do
html_body = """ html_body = """
<p>New account for review: <a href="#{account.ap_id}">@#{account.nickname}</a></p> <p>New account for review: <a href="#{account.ap_id}">@#{account.nickname}</a></p>
<blockquote>#{HTML.strip_tags(account.registration_reason)}</blockquote> <blockquote>#{HTML.strip_tags(account.registration_reason)}</blockquote>
<a href="#{Pleroma.Web.base_url()}/pleroma/admin/#/users/#{account.id}/">Visit AdminFE</a>
<a href="#{Pleroma.Web.Endpoint.url()}/pleroma/admin/#/users/#{account.id}/">Visit AdminFE</a>
""" """


new() new()


+ 9
- 2
lib/pleroma/emails/user_email.ex Dosyayı Görüntüle

@@ -5,15 +5,22 @@
defmodule Pleroma.Emails.UserEmail do defmodule Pleroma.Emails.UserEmail do
@moduledoc "User emails" @moduledoc "User emails"


use Phoenix.Swoosh, view: Pleroma.Web.EmailView, layout: {Pleroma.Web.LayoutView, :email}

alias Pleroma.Config alias Pleroma.Config
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.Router alias Pleroma.Web.Router


import Swoosh.Email
import Phoenix.Swoosh, except: [render_body: 3]
import Pleroma.Config.Helpers, only: [instance_name: 0, sender: 0] import Pleroma.Config.Helpers, only: [instance_name: 0, sender: 0]


def render_body(email, template, assigns \\ %{}) do
email
|> put_new_layout({Pleroma.Web.LayoutView, :email})
|> put_new_view(Pleroma.Web.EmailView)
|> Phoenix.Swoosh.render_body(template, assigns)
end

defp recipient(email, nil), do: email defp recipient(email, nil), do: email
defp recipient(email, name), do: {name, email} defp recipient(email, name), do: {name, email}
defp recipient(%User{} = user), do: recipient(user.email, user.name) defp recipient(%User{} = user), do: recipient(user.email, user.name)


+ 2
- 2
lib/pleroma/emoji/formatter.ex Dosyayı Görüntüle

@@ -5,7 +5,7 @@
defmodule Pleroma.Emoji.Formatter do defmodule Pleroma.Emoji.Formatter do
alias Pleroma.Emoji alias Pleroma.Emoji
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.Web
alias Pleroma.Web.Endpoint
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy


def emojify(text) do def emojify(text) do
@@ -44,7 +44,7 @@ defmodule Pleroma.Emoji.Formatter do
Emoji.get_all() Emoji.get_all()
|> Enum.filter(fn {emoji, %Emoji{}} -> String.contains?(text, ":#{emoji}:") end) |> Enum.filter(fn {emoji, %Emoji{}} -> String.contains?(text, ":#{emoji}:") end)
|> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc -> |> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc ->
Map.put(acc, name, to_string(URI.merge(Web.base_url(), file)))
Map.put(acc, name, to_string(URI.merge(Endpoint.url(), file)))
end) end)
end end




+ 1
- 1
lib/pleroma/formatter.ex Dosyayı Görüntüle

@@ -62,7 +62,7 @@ defmodule Pleroma.Formatter do


def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do
tag = String.downcase(tag) tag = String.downcase(tag)
url = "#{Pleroma.Web.base_url()}/tag/#{tag}"
url = "#{Pleroma.Web.Endpoint.url()}/tag/#{tag}"


link = link =
Phoenix.HTML.Tag.content_tag(:a, tag_text, Phoenix.HTML.Tag.content_tag(:a, tag_text,


+ 1
- 3
lib/pleroma/gun.ex Dosyayı Görüntüle

@@ -11,9 +11,7 @@ defmodule Pleroma.Gun do
@callback await(pid(), reference()) :: {:response, :fin, 200, []} @callback await(pid(), reference()) :: {:response, :fin, 200, []}
@callback set_owner(pid(), pid()) :: :ok @callback set_owner(pid(), pid()) :: :ok


@api Pleroma.Config.get([Pleroma.Gun], Pleroma.Gun.API)

defp api, do: @api
defp api, do: Pleroma.Config.get([Pleroma.Gun], Pleroma.Gun.API)


def open(host, port, opts), do: api().open(host, port, opts) def open(host, port, opts), do: api().open(host, port, opts)




+ 3
- 3
lib/pleroma/gun/connection_pool/reclaimer.ex Dosyayı Görüntüle

@@ -5,11 +5,11 @@
defmodule Pleroma.Gun.ConnectionPool.Reclaimer do defmodule Pleroma.Gun.ConnectionPool.Reclaimer do
use GenServer, restart: :temporary use GenServer, restart: :temporary


@registry Pleroma.Gun.ConnectionPool
defp registry, do: Pleroma.Gun.ConnectionPool


def start_monitor do def start_monitor do
pid = pid =
case :gen_server.start(__MODULE__, [], name: {:via, Registry, {@registry, "reclaimer"}}) do
case :gen_server.start(__MODULE__, [], name: {:via, Registry, {registry(), "reclaimer"}}) do
{:ok, pid} -> {:ok, pid} ->
pid pid


@@ -46,7 +46,7 @@ defmodule Pleroma.Gun.ConnectionPool.Reclaimer do
# {worker_pid, crf, last_reference} end) # {worker_pid, crf, last_reference} end)
unused_conns = unused_conns =
Registry.select( Registry.select(
@registry,
registry(),
[ [
{{:_, :"$1", {:_, :"$2", :"$3", :"$4"}}, [{:==, :"$2", []}], [{{:"$1", :"$3", :"$4"}}]} {{:_, :"$1", {:_, :"$2", :"$3", :"$4"}}, [{:==, :"$2", []}], [{{:"$1", :"$3", :"$4"}}]}
] ]


+ 5
- 5
lib/pleroma/gun/connection_pool/worker.ex Dosyayı Görüntüle

@@ -6,10 +6,10 @@ defmodule Pleroma.Gun.ConnectionPool.Worker do
alias Pleroma.Gun alias Pleroma.Gun
use GenServer, restart: :temporary use GenServer, restart: :temporary


@registry Pleroma.Gun.ConnectionPool
defp registry, do: Pleroma.Gun.ConnectionPool


def start_link([key | _] = opts) do def start_link([key | _] = opts) do
GenServer.start_link(__MODULE__, opts, name: {:via, Registry, {@registry, key}})
GenServer.start_link(__MODULE__, opts, name: {:via, Registry, {registry(), key}})
end end


@impl true @impl true
@@ -24,7 +24,7 @@ defmodule Pleroma.Gun.ConnectionPool.Worker do
time = :erlang.monotonic_time(:millisecond) time = :erlang.monotonic_time(:millisecond)


{_, _} = {_, _} =
Registry.update_value(@registry, key, fn _ ->
Registry.update_value(registry(), key, fn _ ->
{conn_pid, [client_pid], 1, time} {conn_pid, [client_pid], 1, time}
end) end)


@@ -65,7 +65,7 @@ defmodule Pleroma.Gun.ConnectionPool.Worker do
time = :erlang.monotonic_time(:millisecond) time = :erlang.monotonic_time(:millisecond)


{{conn_pid, used_by, _, _}, _} = {{conn_pid, used_by, _, _}, _} =
Registry.update_value(@registry, key, fn {conn_pid, used_by, crf, last_reference} ->
Registry.update_value(registry(), key, fn {conn_pid, used_by, crf, last_reference} ->
{conn_pid, [client_pid | used_by], crf(time - last_reference, crf), time} {conn_pid, [client_pid | used_by], crf(time - last_reference, crf), time}
end) end)


@@ -92,7 +92,7 @@ defmodule Pleroma.Gun.ConnectionPool.Worker do
@impl true @impl true
def handle_call(:remove_client, {client_pid, _}, %{key: key} = state) do def handle_call(:remove_client, {client_pid, _}, %{key: key} = state) do
{{_conn_pid, used_by, _crf, _last_reference}, _} = {{_conn_pid, used_by, _crf, _last_reference}, _} =
Registry.update_value(@registry, key, fn {conn_pid, used_by, crf, last_reference} ->
Registry.update_value(registry(), key, fn {conn_pid, used_by, crf, last_reference} ->
{conn_pid, List.delete(used_by, client_pid), crf, last_reference} {conn_pid, List.delete(used_by, client_pid), crf, last_reference}
end) end)




+ 0
- 35
lib/pleroma/html.ex Dosyayı Görüntüle

@@ -49,31 +49,6 @@ defmodule Pleroma.HTML do
def filter_tags(html), do: filter_tags(html, nil) def filter_tags(html), do: filter_tags(html, nil)
def strip_tags(html), do: filter_tags(html, FastSanitize.Sanitizer.StripTags) def strip_tags(html), do: filter_tags(html, FastSanitize.Sanitizer.StripTags)


def get_cached_scrubbed_html_for_activity(
content,
scrubbers,
activity,
key \\ "",
callback \\ fn x -> x end
) do
key = "#{key}#{generate_scrubber_signature(scrubbers)}|#{activity.id}"

@cachex.fetch!(:scrubber_cache, key, fn _key ->
object = Pleroma.Object.normalize(activity, fetch: false)
ensure_scrubbed_html(content, scrubbers, object.data["fake"] || false, callback)
end)
end

def get_cached_stripped_html_for_activity(content, activity, key) do
get_cached_scrubbed_html_for_activity(
content,
FastSanitize.Sanitizer.StripTags,
activity,
key,
&HtmlEntities.decode/1
)
end

def ensure_scrubbed_html( def ensure_scrubbed_html(
content, content,
scrubbers, scrubbers,
@@ -92,16 +67,6 @@ defmodule Pleroma.HTML do
end end
end end


defp generate_scrubber_signature(scrubber) when is_atom(scrubber) do
generate_scrubber_signature([scrubber])
end

defp generate_scrubber_signature(scrubbers) do
Enum.reduce(scrubbers, "", fn scrubber, signature ->
"#{signature}#{to_string(scrubber)}"
end)
end

def extract_first_external_url_from_object(%{data: %{"content" => content}} = object) def extract_first_external_url_from_object(%{data: %{"content" => content}} = object)
when is_binary(content) do when is_binary(content) do
unless object.data["fake"] do unless object.data["fake"] do


+ 2
- 2
lib/pleroma/http/adapter_helper/gun.ex Dosyayı Görüntüle

@@ -54,8 +54,8 @@ defmodule Pleroma.HTTP.AdapterHelper.Gun do
Config.get([:pools, pool, :recv_timeout], default) Config.get([:pools, pool, :recv_timeout], default)
end end


@prefix Pleroma.Gun.ConnectionPool
def limiter_setup do def limiter_setup do
prefix = Pleroma.Gun.ConnectionPool
wait = Config.get([:connections_pool, :connection_acquisition_wait]) wait = Config.get([:connections_pool, :connection_acquisition_wait])
retries = Config.get([:connections_pool, :connection_acquisition_retries]) retries = Config.get([:connections_pool, :connection_acquisition_retries])


@@ -66,7 +66,7 @@ defmodule Pleroma.HTTP.AdapterHelper.Gun do
max_waiting = Keyword.get(opts, :max_waiting, 10) max_waiting = Keyword.get(opts, :max_waiting, 10)


result = result =
ConcurrentLimiter.new(:"#{@prefix}.#{name}", max_running, max_waiting,
ConcurrentLimiter.new(:"#{prefix}.#{name}", max_running, max_waiting,
wait: wait, wait: wait,
max_retries: retries max_retries: retries
) )


+ 2
- 2
lib/pleroma/http/web_push.ex Dosyayı Görüntüle

@@ -5,8 +5,8 @@
defmodule Pleroma.HTTP.WebPush do defmodule Pleroma.HTTP.WebPush do
@moduledoc false @moduledoc false


def post(url, payload, headers) do
def post(url, payload, headers, options \\ []) do
list_headers = Map.to_list(headers) list_headers = Map.to_list(headers)
Pleroma.HTTP.post(url, payload, list_headers)
Pleroma.HTTP.post(url, payload, list_headers, options)
end end
end end

+ 6
- 0
lib/pleroma/maps.ex Dosyayı Görüntüle

@@ -12,4 +12,10 @@ defmodule Pleroma.Maps do
_ -> map _ -> map
end end
end end

def safe_put_in(data, keys, value) when is_map(data) and is_list(keys) do
Kernel.put_in(data, keys, value)
rescue
_ -> data
end
end end

+ 1
- 1
lib/pleroma/object.ex Dosyayı Görüntüle

@@ -366,7 +366,7 @@ defmodule Pleroma.Object do
end end


def local?(%Object{data: %{"id" => id}}) do def local?(%Object{data: %{"id" => id}}) do
String.starts_with?(id, Pleroma.Web.base_url() <> "/")
String.starts_with?(id, Pleroma.Web.Endpoint.url() <> "/")
end end


def replies(object, opts \\ []) do def replies(object, opts \\ []) do


+ 8
- 2
lib/pleroma/object/fetcher.ex Dosyayı Görüntüle

@@ -4,6 +4,7 @@


defmodule Pleroma.Object.Fetcher do defmodule Pleroma.Object.Fetcher do
alias Pleroma.HTTP alias Pleroma.HTTP
alias Pleroma.Maps
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Object.Containment alias Pleroma.Object.Containment
alias Pleroma.Repo alias Pleroma.Repo
@@ -101,6 +102,9 @@ defmodule Pleroma.Object.Fetcher do
{:transmogrifier, {:error, {:reject, e}}} -> {:transmogrifier, {:error, {:reject, e}}} ->
{:reject, e} {:reject, e}


{:transmogrifier, {:reject, e}} ->
{:reject, e}

{:transmogrifier, _} = e -> {:transmogrifier, _} = e ->
{:error, e} {:error, e}


@@ -124,12 +128,14 @@ defmodule Pleroma.Object.Fetcher do
defp prepare_activity_params(data) do defp prepare_activity_params(data) do
%{ %{
"type" => "Create", "type" => "Create",
"to" => data["to"] || [],
"cc" => data["cc"] || [],
# Should we seriously keep this attributedTo thing? # Should we seriously keep this attributedTo thing?
"actor" => data["actor"] || data["attributedTo"], "actor" => data["actor"] || data["attributedTo"],
"object" => data "object" => data
} }
|> Maps.put_if_present("to", data["to"])
|> Maps.put_if_present("cc", data["cc"])
|> Maps.put_if_present("bto", data["bto"])
|> Maps.put_if_present("bcc", data["bcc"])
end end


def fetch_object_from_id!(id, options \\ []) do def fetch_object_from_id!(id, options \\ []) do


+ 1
- 1
lib/pleroma/reverse_proxy.ex Dosyayı Görüntüle

@@ -411,7 +411,7 @@ defmodule Pleroma.ReverseProxy do
{:ok, :no_duration_limit, :no_duration_limit} {:ok, :no_duration_limit, :no_duration_limit}
end end


defp client, do: Pleroma.ReverseProxy.Client
defp client, do: Pleroma.ReverseProxy.Client.Wrapper


defp track_failed_url(url, error, opts) do defp track_failed_url(url, error, opts) do
ttl = ttl =


+ 0
- 18
lib/pleroma/reverse_proxy/client.ex Dosyayı Görüntüle

@@ -17,22 +17,4 @@ defmodule Pleroma.ReverseProxy.Client do
@callback stream_body(map()) :: {:ok, binary(), map()} | :done | {:error, atom() | String.t()} @callback stream_body(map()) :: {:ok, binary(), map()} | :done | {:error, atom() | String.t()}


@callback close(reference() | pid() | map()) :: :ok @callback close(reference() | pid() | map()) :: :ok

def request(method, url, headers, body \\ "", opts \\ []) do
client().request(method, url, headers, body, opts)
end

def stream_body(ref), do: client().stream_body(ref)

def close(ref), do: client().close(ref)

defp client do
:tesla
|> Application.get_env(:adapter)
|> client()
end

defp client(Tesla.Adapter.Hackney), do: Pleroma.ReverseProxy.Client.Hackney
defp client(Tesla.Adapter.Gun), do: Pleroma.ReverseProxy.Client.Tesla
defp client(_), do: Pleroma.Config.get!(Pleroma.ReverseProxy.Client)
end end

+ 29
- 0
lib/pleroma/reverse_proxy/client/wrapper.ex Dosyayı Görüntüle

@@ -0,0 +1,29 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.ReverseProxy.Client.Wrapper do
@moduledoc "Meta-client that calls the appropriate client from the config."
@behaviour Pleroma.ReverseProxy.Client

@impl true
def request(method, url, headers, body \\ "", opts \\ []) do
client().request(method, url, headers, body, opts)
end

@impl true
def stream_body(ref), do: client().stream_body(ref)

@impl true
def close(ref), do: client().close(ref)

defp client do
:tesla
|> Application.get_env(:adapter)
|> client()
end

defp client(Tesla.Adapter.Hackney), do: Pleroma.ReverseProxy.Client.Hackney
defp client(Tesla.Adapter.Gun), do: Pleroma.ReverseProxy.Client.Tesla
defp client(_), do: Pleroma.Config.get!(Pleroma.ReverseProxy.Client)
end

+ 14
- 4
lib/pleroma/upload.ex Dosyayı Görüntüle

@@ -23,6 +23,9 @@ defmodule Pleroma.Upload do
is once created permanent and changing it (especially in uploaders) is probably a bad idea! is once created permanent and changing it (especially in uploaders) is probably a bad idea!
* `:tempfile` - path to the temporary file. Prefer in-place changes on the file rather than changing the * `:tempfile` - path to the temporary file. Prefer in-place changes on the file rather than changing the
path as the temporary file is also tracked by `Plug.Upload{}` and automatically deleted once the request is over. path as the temporary file is also tracked by `Plug.Upload{}` and automatically deleted once the request is over.
* `:width` - width of the media in pixels
* `:height` - height of the media in pixels
* `:blurhash` - string hash of the image encoded with the blurhash algorithm (https://blurha.sh/)


Related behaviors: Related behaviors:


@@ -32,6 +35,7 @@ defmodule Pleroma.Upload do
""" """
alias Ecto.UUID alias Ecto.UUID
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.Maps
require Logger require Logger


@type source :: @type source ::
@@ -53,9 +57,12 @@ defmodule Pleroma.Upload do
name: String.t(), name: String.t(),
tempfile: String.t(), tempfile: String.t(),
content_type: String.t(), content_type: String.t(),
width: integer(),
height: integer(),
blurhash: String.t(),
path: String.t() path: String.t()
} }
defstruct [:id, :name, :tempfile, :content_type, :path]
defstruct [:id, :name, :tempfile, :content_type, :width, :height, :blurhash, :path]


defp get_description(opts, upload) do defp get_description(opts, upload) do
case {opts[:description], Pleroma.Config.get([Pleroma.Upload, :default_description])} do case {opts[:description], Pleroma.Config.get([Pleroma.Upload, :default_description])} do
@@ -89,9 +96,12 @@ defmodule Pleroma.Upload do
"mediaType" => upload.content_type, "mediaType" => upload.content_type,
"href" => url_from_spec(upload, opts.base_url, url_spec) "href" => url_from_spec(upload, opts.base_url, url_spec)
} }
|> Maps.put_if_present("width", upload.width)
|> Maps.put_if_present("height", upload.height)
], ],
"name" => description "name" => description
}}
}
|> Maps.put_if_present("blurhash", upload.blurhash)}
else else
{:description_limit, _} -> {:description_limit, _} ->
{:error, :description_too_long} {:error, :description_too_long}
@@ -225,7 +235,7 @@ defmodule Pleroma.Upload do


case uploader do case uploader do
Pleroma.Uploaders.Local -> Pleroma.Uploaders.Local ->
upload_base_url || Pleroma.Web.base_url() <> "/media/"
upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/"


Pleroma.Uploaders.S3 -> Pleroma.Uploaders.S3 ->
bucket = Config.get([Pleroma.Uploaders.S3, :bucket]) bucket = Config.get([Pleroma.Uploaders.S3, :bucket])
@@ -251,7 +261,7 @@ defmodule Pleroma.Upload do
end end


_ -> _ ->
public_endpoint || upload_base_url || Pleroma.Web.base_url() <> "/media/"
public_endpoint || upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/"
end end
end end
end end

+ 45
- 0
lib/pleroma/upload/filter/analyze_metadata.ex Dosyayı Görüntüle

@@ -0,0 +1,45 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
@moduledoc """
Extracts metadata about the upload, such as width/height
"""
require Logger

@behaviour Pleroma.Upload.Filter

@spec filter(Pleroma.Upload.t()) ::
{:ok, :filtered, Pleroma.Upload.t()} | {:ok, :noop} | {:error, String.t()}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _} = upload) do
try do
image =
file
|> Mogrify.open()
|> Mogrify.verbose()

upload =
upload
|> Map.put(:width, image.width)
|> Map.put(:height, image.height)
|> Map.put(:blurhash, get_blurhash(file))

{:ok, :filtered, upload}
rescue
e in ErlangError ->
Logger.warn("#{__MODULE__}: #{inspect(e)}")
{:ok, :noop}
end
end

def filter(_), do: {:ok, :noop}

defp get_blurhash(file) do
with {:ok, blurhash} <- :eblurhash.magick(file) do
blurhash
else
_ -> nil
end
end
end

+ 2
- 2
lib/pleroma/uploaders/uploader.ex Dosyayı Görüntüle

@@ -35,7 +35,7 @@ defmodule Pleroma.Uploaders.Uploader do


""" """
@type file_spec :: {:file | :url, String.t()} @type file_spec :: {:file | :url, String.t()}
@callback put_file(Pleroma.Upload.t()) ::
@callback put_file(upload :: struct()) ::
:ok | {:ok, file_spec()} | {:error, String.t()} | :wait_callback :ok | {:ok, file_spec()} | {:error, String.t()} | :wait_callback


@callback delete_file(file :: String.t()) :: :ok | {:error, String.t()} @callback delete_file(file :: String.t()) :: :ok | {:error, String.t()}
@@ -46,7 +46,7 @@ defmodule Pleroma.Uploaders.Uploader do
| {:error, Plug.Conn.t(), String.t()} | {:error, Plug.Conn.t(), String.t()}
@optional_callbacks http_callback: 2 @optional_callbacks http_callback: 2


@spec put_file(module(), Pleroma.Upload.t()) :: {:ok, file_spec()} | {:error, String.t()}
@spec put_file(module(), upload :: struct()) :: {:ok, file_spec()} | {:error, String.t()}
def put_file(uploader, upload) do def put_file(uploader, upload) do
case uploader.put_file(upload) do case uploader.put_file(upload) do
:ok -> {:ok, {:file, upload.path}} :ok -> {:ok, {:file, upload.path}}


+ 4
- 4
lib/pleroma/user.ex Dosyayı Görüntüle

@@ -27,13 +27,13 @@ defmodule Pleroma.User do
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.UserRelationship alias Pleroma.UserRelationship
alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Builder alias Pleroma.Web.ActivityPub.Builder
alias Pleroma.Web.ActivityPub.Pipeline alias Pleroma.Web.ActivityPub.Pipeline
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
alias Pleroma.Web.Endpoint
alias Pleroma.Web.OAuth alias Pleroma.Web.OAuth
alias Pleroma.Web.RelMe alias Pleroma.Web.RelMe
alias Pleroma.Workers.BackgroundWorker alias Pleroma.Workers.BackgroundWorker
@@ -360,7 +360,7 @@ defmodule Pleroma.User do


_ -> _ ->
unless options[:no_default] do unless options[:no_default] do
Config.get([:assets, :default_user_avatar], "#{Web.base_url()}/images/avi.png")
Config.get([:assets, :default_user_avatar], "#{Endpoint.url()}/images/avi.png")
end end
end end
end end
@@ -368,13 +368,13 @@ defmodule Pleroma.User do
def banner_url(user, options \\ []) do def banner_url(user, options \\ []) do
case user.banner do case user.banner do
%{"url" => [%{"href" => href} | _]} -> href %{"url" => [%{"href" => href} | _]} -> href
_ -> !options[:no_default] && "#{Web.base_url()}/images/banner.png"
_ -> !options[:no_default] && "#{Endpoint.url()}/images/banner.png"
end end
end end


# Should probably be renamed or removed # Should probably be renamed or removed
@spec ap_id(User.t()) :: String.t() @spec ap_id(User.t()) :: String.t()
def ap_id(%User{nickname: nickname}), do: "#{Web.base_url()}/users/#{nickname}"
def ap_id(%User{nickname: nickname}), do: "#{Endpoint.url()}/users/#{nickname}"


@spec ap_followers(User.t()) :: String.t() @spec ap_followers(User.t()) :: String.t()
def ap_followers(%User{follower_address: fa}) when is_binary(fa), do: fa def ap_followers(%User{follower_address: fa}) when is_binary(fa), do: fa


+ 4
- 18
lib/pleroma/web.ex Dosyayı Görüntüle

@@ -35,9 +35,10 @@ defmodule Pleroma.Web do
import Plug.Conn import Plug.Conn


import Pleroma.Web.Gettext import Pleroma.Web.Gettext
import Pleroma.Web.Router.Helpers
import Pleroma.Web.TranslationHelpers import Pleroma.Web.TranslationHelpers


alias Pleroma.Web.Router.Helpers, as: Routes

plug(:set_put_layout) plug(:set_put_layout)


defp set_put_layout(conn, _) do defp set_put_layout(conn, _) do
@@ -131,7 +132,8 @@ defmodule Pleroma.Web do


import Pleroma.Web.ErrorHelpers import Pleroma.Web.ErrorHelpers
import Pleroma.Web.Gettext import Pleroma.Web.Gettext
import Pleroma.Web.Router.Helpers

alias Pleroma.Web.Router.Helpers, as: Routes


require Logger require Logger


@@ -229,20 +231,4 @@ defmodule Pleroma.Web do
defmacro __using__(which) when is_atom(which) do defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, []) apply(__MODULE__, which, [])
end end

def base_url do
Pleroma.Web.Endpoint.url()
end

# TODO: Change to Phoenix.Router.routes/1 for Phoenix 1.6.0+
def get_api_routes do
Pleroma.Web.Router.__routes__()
|> Enum.reject(fn r -> r.plug == Pleroma.Web.Fallback.RedirectController end)
|> Enum.map(fn r ->
r.path
|> String.split("/", trim: true)
|> List.first()
end)
|> Enum.uniq()
end
end end

+ 1
- 1
lib/pleroma/web/activity_pub/activity_pub.ex Dosyayı Görüntüle

@@ -88,7 +88,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do


defp increase_replies_count_if_reply(_create_data), do: :noop defp increase_replies_count_if_reply(_create_data), do: :noop


@object_types ~w[ChatMessage Question Answer Audio Video Event Article]
@object_types ~w[ChatMessage Question Answer Audio Video Event Article Note]
@impl true @impl true
def persist(%{"type" => type} = object, meta) when type in @object_types do def persist(%{"type" => type} = object, meta) when type in @object_types do
with {:ok, object} <- Object.create(object) do with {:ok, object} <- Object.create(object) do


+ 1
- 1
lib/pleroma/web/activity_pub/activity_pub/persisting.ex Dosyayı Görüntüle

@@ -3,5 +3,5 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only


defmodule Pleroma.Web.ActivityPub.ActivityPub.Persisting do defmodule Pleroma.Web.ActivityPub.ActivityPub.Persisting do
@callback persist(map(), keyword()) :: {:ok, Activity.t() | Object.t()}
@callback persist(map(), keyword()) :: {:ok, struct()}
end end

+ 2
- 6
lib/pleroma/web/activity_pub/activity_pub/streaming.ex Dosyayı Görüntüle

@@ -3,10 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only


defmodule Pleroma.Web.ActivityPub.ActivityPub.Streaming do defmodule Pleroma.Web.ActivityPub.ActivityPub.Streaming do
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.User

@callback stream_out(Activity.t()) :: any()
@callback stream_out_participations(Object.t(), User.t()) :: any()
@callback stream_out(struct()) :: any()
@callback stream_out_participations(struct(), struct()) :: any()
end end

+ 1
- 1
lib/pleroma/web/activity_pub/builder.ex Dosyayı Görüntüle

@@ -223,7 +223,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
[actor.follower_address] [actor.follower_address]


public? and Visibility.is_local_public?(object) -> public? and Visibility.is_local_public?(object) ->
[actor.follower_address, object.data["actor"], Pleroma.Constants.as_local_public()]
[actor.follower_address, object.data["actor"], Utils.as_local_public()]


public? -> public? ->
[actor.follower_address, object.data["actor"], Pleroma.Constants.as_public()] [actor.follower_address, object.data["actor"], Pleroma.Constants.as_public()]


+ 2
- 2
lib/pleroma/web/activity_pub/mrf/no_empty_policy.ex Dosyayı Görüntüle

@@ -6,7 +6,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoEmptyPolicy do
@moduledoc "Filter local activities which have no content" @moduledoc "Filter local activities which have no content"
@behaviour Pleroma.Web.ActivityPub.MRF @behaviour Pleroma.Web.ActivityPub.MRF


alias Pleroma.Web
alias Pleroma.Web.Endpoint


@impl true @impl true
def filter(%{"actor" => actor} = object) do def filter(%{"actor" => actor} = object) do
@@ -24,7 +24,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoEmptyPolicy do
def filter(object), do: {:ok, object} def filter(object), do: {:ok, object}


defp is_local?(actor) do defp is_local?(actor) do
if actor |> String.starts_with?("#{Web.base_url()}") do
if actor |> String.starts_with?("#{Endpoint.url()}") do
true true
else else
false false


+ 23
- 1
lib/pleroma/web/activity_pub/mrf/simple_policy.ex Dosyayı Görüntüle

@@ -177,6 +177,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do


defp check_banner_removal(_actor_info, object), do: {:ok, object} defp check_banner_removal(_actor_info, object), do: {:ok, object}


defp check_object(%{"object" => object} = activity) do
with {:ok, _object} <- filter(object) do
{:ok, activity}
end
end

defp check_object(object), do: {:ok, object}

@impl true @impl true
def filter(%{"type" => "Delete", "actor" => actor} = object) do def filter(%{"type" => "Delete", "actor" => actor} = object) do
%{host: actor_host} = URI.parse(actor) %{host: actor_host} = URI.parse(actor)
@@ -202,7 +210,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
{:ok, object} <- check_media_nsfw(actor_info, object), {:ok, object} <- check_media_nsfw(actor_info, object),
{:ok, object} <- check_ftl_removal(actor_info, object), {:ok, object} <- check_ftl_removal(actor_info, object),
{:ok, object} <- check_followers_only(actor_info, object), {:ok, object} <- check_followers_only(actor_info, object),
{:ok, object} <- check_report_removal(actor_info, object) do
{:ok, object} <- check_report_removal(actor_info, object),
{:ok, object} <- check_object(object) do
{:ok, object} {:ok, object}
else else
{:reject, nil} -> {:reject, "[SimplePolicy]"} {:reject, nil} -> {:reject, "[SimplePolicy]"}
@@ -227,6 +236,19 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
end end
end end


def filter(object) when is_binary(object) do
uri = URI.parse(object)

with {:ok, object} <- check_accept(uri, object),
{:ok, object} <- check_reject(uri, object) do
{:ok, object}
else
{:reject, nil} -> {:reject, "[SimplePolicy]"}
{:reject, _} = e -> e
_ -> {:reject, "[SimplePolicy]"}
end
end

def filter(object), do: {:ok, object} def filter(object), do: {:ok, object}


@impl true @impl true


+ 4
- 3
lib/pleroma/web/activity_pub/object_validator.ex Dosyayı Görüntüle

@@ -102,7 +102,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
%{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity, %{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity,
meta meta
) )
when objtype in ~w[Question Answer Audio Video Event Article] do
when objtype in ~w[Question Answer Audio Video Event Article Note] do
with {:ok, object_data} <- cast_and_apply(object), with {:ok, object_data} <- cast_and_apply(object),
meta = Keyword.put(meta, :object_data, object_data |> stringify_keys), meta = Keyword.put(meta, :object_data, object_data |> stringify_keys),
{:ok, create_activity} <- {:ok, create_activity} <-
@@ -115,7 +115,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
end end


def validate(%{"type" => type} = object, meta) def validate(%{"type" => type} = object, meta)
when type in ~w[Event Question Audio Video Article] do
when type in ~w[Event Question Audio Video Article Note] do
validator = validator =
case type do case type do
"Event" -> EventValidator "Event" -> EventValidator
@@ -123,6 +123,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
"Audio" -> AudioVideoValidator "Audio" -> AudioVideoValidator
"Video" -> AudioVideoValidator "Video" -> AudioVideoValidator
"Article" -> ArticleNoteValidator "Article" -> ArticleNoteValidator
"Note" -> ArticleNoteValidator
end end


with {:ok, object} <- with {:ok, object} <-
@@ -194,7 +195,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
EventValidator.cast_and_apply(object) EventValidator.cast_and_apply(object)
end end


def cast_and_apply(%{"type" => "Article"} = object) do
def cast_and_apply(%{"type" => type} = object) when type in ~w[Article Note] do
ArticleNoteValidator.cast_and_apply(object) ArticleNoteValidator.cast_and_apply(object)
end end




+ 1
- 1
lib/pleroma/web/activity_pub/object_validators/announce_validator.ex Dosyayı Görüntüle

@@ -68,7 +68,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
false <- Visibility.is_public?(object) do false <- Visibility.is_public?(object) do
same_actor = object.data["actor"] == actor.ap_id same_actor = object.data["actor"] == actor.ap_id
recipients = get_field(cng, :to) ++ get_field(cng, :cc) recipients = get_field(cng, :to) ++ get_field(cng, :cc)
local_public = Pleroma.Constants.as_local_public()
local_public = Utils.as_local_public()


is_public = is_public =
Enum.member?(recipients, Pleroma.Constants.as_public()) or Enum.member?(recipients, Pleroma.Constants.as_public()) or


+ 7
- 0
lib/pleroma/web/activity_pub/object_validators/answer_validator.ex Dosyayı Görüntüle

@@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do
use Ecto.Schema use Ecto.Schema


alias Pleroma.EctoType.ActivityPub.ObjectValidators alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations


import Ecto.Changeset import Ecto.Changeset
@@ -23,6 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do
field(:name, :string) field(:name, :string)
field(:inReplyTo, ObjectValidators.ObjectID) field(:inReplyTo, ObjectValidators.ObjectID)
field(:attributedTo, ObjectValidators.ObjectID) field(:attributedTo, ObjectValidators.ObjectID)
field(:context, :string)


# TODO: Remove actor on objects # TODO: Remove actor on objects
field(:actor, ObjectValidators.ObjectID) field(:actor, ObjectValidators.ObjectID)
@@ -46,6 +48,11 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do
end end


def changeset(struct, data) do def changeset(struct, data) do
data =
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()

struct struct
|> cast(data, __schema__(:fields)) |> cast(data, __schema__(:fields))
end end


+ 24
- 8
lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex Dosyayı Görüntüle

@@ -50,6 +50,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator do


field(:likes, {:array, ObjectValidators.ObjectID}, default: []) field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
field(:announcements, {:array, ObjectValidators.ObjectID}, default: []) field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])

field(:replies, {:array, ObjectValidators.ObjectID}, default: [])
end end


def cast_and_apply(data) do def cast_and_apply(data) do
@@ -65,25 +67,39 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator do
end end


def cast_data(data) do def cast_data(data) do
data = fix(data)

%__MODULE__{} %__MODULE__{}
|> changeset(data) |> changeset(data)
end end


defp fix_url(%{"url" => url} = data) when is_map(url) do
Map.put(data, "url", url["href"])
end

defp fix_url(%{"url" => url} = data) when is_bitstring(url), do: data
defp fix_url(%{"url" => url} = data) when is_map(url), do: Map.put(data, "url", url["href"])
defp fix_url(data), do: data defp fix_url(data), do: data


defp fix_tag(%{"tag" => tag} = data) when is_list(tag), do: data
defp fix_tag(%{"tag" => tag} = data) when is_map(tag), do: Map.put(data, "tag", [tag])
defp fix_tag(data), do: Map.drop(data, ["tag"])

defp fix_replies(%{"replies" => %{"first" => %{"items" => replies}}} = data)
when is_list(replies),
do: Map.put(data, "replies", replies)

defp fix_replies(%{"replies" => %{"items" => replies}} = data) when is_list(replies),
do: Map.put(data, "replies", replies)

defp fix_replies(%{"replies" => replies} = data) when is_bitstring(replies),
do: Map.drop(data, ["replies"])

defp fix_replies(data), do: data

defp fix(data) do defp fix(data) do
data data
|> CommonFixes.fix_defaults()
|> CommonFixes.fix_attribution()
|> CommonFixes.fix_actor() |> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()
|> fix_url() |> fix_url()
|> fix_tag()
|> fix_replies()
|> Transmogrifier.fix_emoji() |> Transmogrifier.fix_emoji()
|> Transmogrifier.fix_content_map()
end end


def changeset(struct, data) do def changeset(struct, data) do


+ 4
- 2
lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex Dosyayı Görüntüle

@@ -20,6 +20,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
field(:type, :string) field(:type, :string)
field(:href, ObjectValidators.Uri) field(:href, ObjectValidators.Uri)
field(:mediaType, :string, default: "application/octet-stream") field(:mediaType, :string, default: "application/octet-stream")
field(:width, :integer)
field(:height, :integer)
end end
end end


@@ -51,7 +53,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
data = fix_media_type(data) data = fix_media_type(data)


struct struct
|> cast(data, [:type, :href, :mediaType])
|> cast(data, [:type, :href, :mediaType, :width, :height])
|> validate_inclusion(:type, ["Link"]) |> validate_inclusion(:type, ["Link"])
|> validate_required([:type, :href, :mediaType]) |> validate_required([:type, :href, :mediaType])
end end
@@ -59,7 +61,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
def fix_media_type(data) do def fix_media_type(data) do
data = Map.put_new(data, "mediaType", data["mimeType"]) data = Map.put_new(data, "mediaType", data["mimeType"])


if MIME.valid?(data["mediaType"]) do
if is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] do
data data
else else
Map.put(data, "mediaType", "application/octet-stream") Map.put(data, "mediaType", "application/octet-stream")


+ 1
- 2
lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex Dosyayı Görüntüle

@@ -119,9 +119,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do


defp fix(data) do defp fix(data) do
data data
|> CommonFixes.fix_defaults()
|> CommonFixes.fix_attribution()
|> CommonFixes.fix_actor() |> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()
|> Transmogrifier.fix_emoji() |> Transmogrifier.fix_emoji()
|> fix_url() |> fix_url()
|> fix_content() |> fix_content()


+ 35
- 6
lib/pleroma/web/activity_pub/object_validators/common_fixes.ex Dosyayı Görüntüle

@@ -3,26 +3,55 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only


defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Object.Containment alias Pleroma.Object.Containment
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils


# based on Pleroma.Web.ActivityPub.Utils.lazy_put_objects_defaults
def fix_defaults(data) do
def cast_and_filter_recipients(message, field, follower_collection, field_fallback \\ []) do
{:ok, data} = ObjectValidators.Recipients.cast(message[field] || field_fallback)

data =
Enum.reject(data, fn x ->
String.ends_with?(x, "/followers") and x != follower_collection
end)

Map.put(message, field, data)
end

def fix_object_defaults(data) do
%{data: %{"id" => context}, id: context_id} = %{data: %{"id" => context}, id: context_id} =
Utils.create_context(data["context"] || data["conversation"]) Utils.create_context(data["context"] || data["conversation"])


%User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["attributedTo"])

data data
|> Map.put("context", context) |> Map.put("context", context)
|> Map.put("context_id", context_id) |> Map.put("context_id", context_id)
|> cast_and_filter_recipients("to", follower_collection)
|> cast_and_filter_recipients("cc", follower_collection)
|> cast_and_filter_recipients("bto", follower_collection)
|> cast_and_filter_recipients("bcc", follower_collection)
|> Transmogrifier.fix_implicit_addressing(follower_collection)
end end


def fix_attribution(data) do
data
|> Map.put_new("actor", data["attributedTo"])
def fix_activity_addressing(activity, _meta) do
%User{follower_address: follower_collection} = User.get_cached_by_ap_id(activity["actor"])

activity
|> cast_and_filter_recipients("to", follower_collection)
|> cast_and_filter_recipients("cc", follower_collection)
|> cast_and_filter_recipients("bto", follower_collection)
|> cast_and_filter_recipients("bcc", follower_collection)
|> Transmogrifier.fix_implicit_addressing(follower_collection)
end end


def fix_actor(data) do def fix_actor(data) do
actor = Containment.get_actor(data)
actor =
data
|> Map.put_new("actor", data["attributedTo"])
|> Containment.get_actor()


data data
|> Map.put("actor", actor) |> Map.put("actor", actor)


+ 1
- 0
lib/pleroma/web/activity_pub/object_validators/common_validations.ex Dosyayı Görüntüle

@@ -15,6 +15,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do
fields fields
|> Enum.map(fn field -> get_field(cng, field) end) |> Enum.map(fn field -> get_field(cng, field) end)
|> Enum.any?(fn |> Enum.any?(fn
nil -> false
[] -> false [] -> false
_ -> true _ -> true
end) end)


+ 41
- 26
lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex Dosyayı Görüntüle

@@ -10,8 +10,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do


alias Pleroma.EctoType.ActivityPub.ObjectValidators alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
alias Pleroma.Web.ActivityPub.Transmogrifier


import Ecto.Changeset import Ecto.Changeset


@@ -23,6 +25,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
field(:type, :string) field(:type, :string)
field(:to, ObjectValidators.Recipients, default: []) field(:to, ObjectValidators.Recipients, default: [])
field(:cc, ObjectValidators.Recipients, default: []) field(:cc, ObjectValidators.Recipients, default: [])
field(:bto, ObjectValidators.Recipients, default: [])
field(:bcc, ObjectValidators.Recipients, default: [])
field(:object, ObjectValidators.ObjectID) field(:object, ObjectValidators.ObjectID)
field(:expires_at, ObjectValidators.DateTime) field(:expires_at, ObjectValidators.DateTime)


@@ -54,39 +58,37 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
|> cast(data, __schema__(:fields)) |> cast(data, __schema__(:fields))
end end


defp fix_context(data, meta) do
if object = meta[:object_data] do
Map.put_new(data, "context", object["context"])
else
data
end
end
# CommonFixes.fix_activity_addressing adapted for Create specific behavior
defp fix_addressing(data, object) do
%User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["actor"])


defp fix_addressing(data, meta) do
if object = meta[:object_data] do
data
|> Map.put_new("to", object["to"] || [])
|> Map.put_new("cc", object["cc"] || [])
else
data
end
data
|> CommonFixes.cast_and_filter_recipients("to", follower_collection, object["to"])
|> CommonFixes.cast_and_filter_recipients("cc", follower_collection, object["cc"])
|> CommonFixes.cast_and_filter_recipients("bto", follower_collection, object["bto"])
|> CommonFixes.cast_and_filter_recipients("bcc", follower_collection, object["bcc"])
|> Transmogrifier.fix_implicit_addressing(follower_collection)
end end


defp fix(data, meta) do
def fix(data, meta) do
object = meta[:object_data]

data data
|> fix_context(meta)
|> fix_addressing(meta)
|> CommonFixes.fix_actor() |> CommonFixes.fix_actor()
|> Map.put_new("context", object["context"])
|> fix_addressing(object)
end end


defp validate_data(cng, meta) do defp validate_data(cng, meta) do
object = meta[:object_data]

cng cng
|> validate_required([:actor, :type, :object])
|> validate_required([:actor, :type, :object, :to, :cc])
|> validate_inclusion(:type, ["Create"]) |> validate_inclusion(:type, ["Create"])
|> CommonValidations.validate_actor_presence() |> CommonValidations.validate_actor_presence()
|> CommonValidations.validate_any_presence([:to, :cc])
|> validate_actors_match(meta)
|> validate_context_match(meta)
|> validate_actors_match(object)
|> validate_context_match(object)
|> validate_addressing_match(object)
|> validate_object_nonexistence() |> validate_object_nonexistence()
|> validate_object_containment() |> validate_object_containment()
end end
@@ -118,8 +120,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
end) end)
end end


def validate_actors_match(cng, meta) do
attributed_to = meta[:object_data]["attributedTo"] || meta[:object_data]["actor"]
def validate_actors_match(cng, object) do
attributed_to = object["attributedTo"] || object["actor"]


cng cng
|> validate_change(:actor, fn :actor, actor -> |> validate_change(:actor, fn :actor, actor ->
@@ -131,7 +133,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
end) end)
end end


def validate_context_match(cng, %{object_data: %{"context" => object_context}}) do
def validate_context_match(cng, %{"context" => object_context}) do
cng cng
|> validate_change(:context, fn :context, context -> |> validate_change(:context, fn :context, context ->
if context == object_context do if context == object_context do
@@ -142,5 +144,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
end) end)
end end


def validate_context_match(cng, _), do: cng
def validate_addressing_match(cng, object) do
[:to, :cc, :bcc, :bto]
|> Enum.reduce(cng, fn field, cng ->
object_data = object[to_string(field)]

validate_change(cng, field, fn field, data ->
if data == object_data do
[]
else
[{field, "field doesn't match with object (#{inspect(object_data)})"}]
end
end)
end)
end
end end

+ 0
- 29
lib/pleroma/web/activity_pub/object_validators/create_note_validator.ex Dosyayı Görüntüle

@@ -1,29 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateNoteValidator do
use Ecto.Schema

alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator

import Ecto.Changeset

@primary_key false

embedded_schema do
field(:id, ObjectValidators.ObjectID, primary_key: true)
field(:actor, ObjectValidators.ObjectID)
field(:type, :string)
field(:to, ObjectValidators.Recipients, default: [])
field(:cc, ObjectValidators.Recipients, default: [])
field(:bto, ObjectValidators.Recipients, default: [])
field(:bcc, ObjectValidators.Recipients, default: [])
embeds_one(:object, NoteValidator)
end

def cast_data(data) do
cast(%__MODULE__{}, data, __schema__(:fields))
end
end

+ 2
- 2
lib/pleroma/web/activity_pub/object_validators/event_validator.ex Dosyayı Görüntüle

@@ -72,8 +72,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do


defp fix(data) do defp fix(data) do
data data
|> CommonFixes.fix_defaults()
|> CommonFixes.fix_attribution()
|> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()
|> Transmogrifier.fix_emoji() |> Transmogrifier.fix_emoji()
end end




+ 2
- 2
lib/pleroma/web/activity_pub/object_validators/question_validator.ex Dosyayı Görüntüle

@@ -83,8 +83,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do


defp fix(data) do defp fix(data) do
data data
|> CommonFixes.fix_defaults()
|> CommonFixes.fix_attribution()
|> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()
|> Transmogrifier.fix_emoji() |> Transmogrifier.fix_emoji()
|> fix_closed() |> fix_closed()
end end


+ 13
- 13
lib/pleroma/web/activity_pub/pipeline.ex Dosyayı Görüntüle

@@ -15,19 +15,19 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.Federator alias Pleroma.Web.Federator


@side_effects Config.get([:pipeline, :side_effects], SideEffects)
@federator Config.get([:pipeline, :federator], Federator)
@object_validator Config.get([:pipeline, :object_validator], ObjectValidator)
@mrf Config.get([:pipeline, :mrf], MRF)
@activity_pub Config.get([:pipeline, :activity_pub], ActivityPub)
@config Config.get([:pipeline, :config], Config)
defp side_effects, do: Config.get([:pipeline, :side_effects], SideEffects)
defp federator, do: Config.get([:pipeline, :federator], Federator)
defp object_validator, do: Config.get([:pipeline, :object_validator], ObjectValidator)
defp mrf, do: Config.get([:pipeline, :mrf], MRF)
defp activity_pub, do: Config.get([:pipeline, :activity_pub], ActivityPub)
defp config, do: Config.get([:pipeline, :config], Config)


@spec common_pipeline(map(), keyword()) :: @spec common_pipeline(map(), keyword()) ::
{:ok, Activity.t() | Object.t(), keyword()} | {:error, any()} {:ok, Activity.t() | Object.t(), keyword()} | {:error, any()}
def common_pipeline(object, meta) do def common_pipeline(object, meta) do
case Repo.transaction(fn -> do_common_pipeline(object, meta) end, Utils.query_timeout()) do case Repo.transaction(fn -> do_common_pipeline(object, meta) end, Utils.query_timeout()) do
{:ok, {:ok, activity, meta}} -> {:ok, {:ok, activity, meta}} ->
@side_effects.handle_after_transaction(meta)
side_effects().handle_after_transaction(meta)
{:ok, activity, meta} {:ok, activity, meta}


{:ok, value} -> {:ok, value} ->
@@ -44,10 +44,10 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
def do_common_pipeline(%{__struct__: _}, _meta), do: {:error, :is_struct} def do_common_pipeline(%{__struct__: _}, _meta), do: {:error, :is_struct}


def do_common_pipeline(message, meta) do def do_common_pipeline(message, meta) do
with {_, {:ok, message, meta}} <- {:validate, @object_validator.validate(message, meta)},
{_, {:ok, message, meta}} <- {:mrf, @mrf.pipeline_filter(message, meta)},
{_, {:ok, message, meta}} <- {:persist, @activity_pub.persist(message, meta)},
{_, {:ok, message, meta}} <- {:side_effects, @side_effects.handle(message, meta)},
with {_, {:ok, message, meta}} <- {:validate, object_validator().validate(message, meta)},
{_, {:ok, message, meta}} <- {:mrf, mrf().pipeline_filter(message, meta)},
{_, {:ok, message, meta}} <- {:persist, activity_pub().persist(message, meta)},
{_, {:ok, message, meta}} <- {:side_effects, side_effects().handle(message, meta)},
{_, {:ok, _}} <- {:federation, maybe_federate(message, meta)} do {_, {:ok, _}} <- {:federation, maybe_federate(message, meta)} do
{:ok, message, meta} {:ok, message, meta}
else else
@@ -60,7 +60,7 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do


defp maybe_federate(%Activity{} = activity, meta) do defp maybe_federate(%Activity{} = activity, meta) do
with {:ok, local} <- Keyword.fetch(meta, :local) do with {:ok, local} <- Keyword.fetch(meta, :local) do
do_not_federate = meta[:do_not_federate] || !@config.get([:instance, :federating])
do_not_federate = meta[:do_not_federate] || !config().get([:instance, :federating])


if !do_not_federate and local and not Visibility.is_local_public?(activity) do if !do_not_federate and local and not Visibility.is_local_public?(activity) do
activity = activity =
@@ -70,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
activity activity
end end


@federator.publish(activity)
federator().publish(activity)
{:ok, :federated} {:ok, :federated}
else else
{:ok, :not_federated} {:ok, :not_federated}


+ 1
- 1
lib/pleroma/web/activity_pub/publisher.ex Dosyayı Görüntüle

@@ -272,7 +272,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
}, },
%{ %{
"rel" => "http://ostatus.org/schema/1.0/subscribe", "rel" => "http://ostatus.org/schema/1.0/subscribe",
"template" => "#{Pleroma.Web.base_url()}/ostatus_subscribe?acct={uri}"
"template" => "#{Pleroma.Web.Endpoint.url()}/ostatus_subscribe?acct={uri}"
} }
] ]
end end


+ 14
- 1
lib/pleroma/web/activity_pub/side_effects.ex Dosyayı Görüntüle

@@ -203,6 +203,19 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
Object.increase_replies_count(in_reply_to) Object.increase_replies_count(in_reply_to)
end end


reply_depth = (meta[:depth] || 0) + 1

# FIXME: Force inReplyTo to replies
if Pleroma.Web.Federator.allowed_thread_distance?(reply_depth) and
object.data["replies"] != nil do
for reply_id <- object.data["replies"] do
Pleroma.Workers.RemoteFetcherWorker.enqueue("fetch_remote", %{
"id" => reply_id,
"depth" => reply_depth
})
end
end

ConcurrentLimiter.limit(Pleroma.Web.RichMedia.Helpers, fn -> ConcurrentLimiter.limit(Pleroma.Web.RichMedia.Helpers, fn ->
Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end) Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end)
end) end)
@@ -423,7 +436,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
end end


def handle_object_creation(%{"type" => objtype} = object, meta) def handle_object_creation(%{"type" => objtype} = object, meta)
when objtype in ~w[Audio Video Question Event Article] do
when objtype in ~w[Audio Video Question Event Article Note] do
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
{:ok, object, meta} {:ok, object, meta}
end end


+ 53
- 54
lib/pleroma/web/activity_pub/transmogrifier.ex Dosyayı Görüntüle

@@ -43,7 +43,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> fix_content_map() |> fix_content_map()
|> fix_addressing() |> fix_addressing()
|> fix_summary() |> fix_summary()
|> fix_type(options)
end end


def fix_summary(%{"summary" => nil} = object) do def fix_summary(%{"summary" => nil} = object) do
@@ -72,17 +71,21 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end end
end end


def fix_explicit_addressing(
%{"to" => to, "cc" => cc} = object,
explicit_mentions,
follower_collection
) do
explicit_to = Enum.filter(to, fn x -> x in explicit_mentions end)
# if directMessage flag is set to true, leave the addressing alone
def fix_explicit_addressing(%{"directMessage" => true} = object, _follower_collection),
do: object

def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, follower_collection) do
explicit_mentions =
Utils.determine_explicit_mentions(object) ++
[Pleroma.Constants.as_public(), follower_collection]


explicit_to = Enum.filter(to, fn x -> x in explicit_mentions end)
explicit_cc = Enum.filter(to, fn x -> x not in explicit_mentions end) explicit_cc = Enum.filter(to, fn x -> x not in explicit_mentions end)


final_cc = final_cc =
(cc ++ explicit_cc) (cc ++ explicit_cc)
|> Enum.filter(& &1)
|> Enum.reject(fn x -> String.ends_with?(x, "/followers") and x != follower_collection end) |> Enum.reject(fn x -> String.ends_with?(x, "/followers") and x != follower_collection end)
|> Enum.uniq() |> Enum.uniq()


@@ -91,29 +94,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> Map.put("cc", final_cc) |> Map.put("cc", final_cc)
end end


def fix_explicit_addressing(object, _explicit_mentions, _followers_collection), do: object

# if directMessage flag is set to true, leave the addressing alone
def fix_explicit_addressing(%{"directMessage" => true} = object), do: object

def fix_explicit_addressing(object) do
explicit_mentions = Utils.determine_explicit_mentions(object)

%User{follower_address: follower_collection} =
object
|> Containment.get_actor()
|> User.get_cached_by_ap_id()

explicit_mentions =
explicit_mentions ++
[
Pleroma.Constants.as_public(),
follower_collection
]

fix_explicit_addressing(object, explicit_mentions, follower_collection)
end

# if as:Public is addressed, then make sure the followers collection is also addressed # if as:Public is addressed, then make sure the followers collection is also addressed
# so that the activities will be delivered to local users. # so that the activities will be delivered to local users.
def fix_implicit_addressing(%{"to" => to, "cc" => cc} = object, followers_collection) do def fix_implicit_addressing(%{"to" => to, "cc" => cc} = object, followers_collection) do
@@ -137,19 +117,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end end
end end


def fix_implicit_addressing(object, _), do: object

def fix_addressing(object) do def fix_addressing(object) do
{:ok, %User{} = user} = User.get_or_fetch_by_ap_id(object["actor"])
followers_collection = User.ap_followers(user)
{:ok, %User{follower_address: follower_collection}} =
object
|> Containment.get_actor()
|> User.get_or_fetch_by_ap_id()


object object
|> fix_addressing_list("to") |> fix_addressing_list("to")
|> fix_addressing_list("cc") |> fix_addressing_list("cc")
|> fix_addressing_list("bto") |> fix_addressing_list("bto")
|> fix_addressing_list("bcc") |> fix_addressing_list("bcc")
|> fix_explicit_addressing()
|> fix_implicit_addressing(followers_collection)
|> fix_explicit_addressing(follower_collection)
|> fix_implicit_addressing(follower_collection)
end end


def fix_actor(%{"attributedTo" => actor} = object) do def fix_actor(%{"attributedTo" => actor} = object) do
@@ -223,10 +203,17 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do


media_type = media_type =
cond do cond do
is_map(url) && MIME.valid?(url["mediaType"]) -> url["mediaType"]
MIME.valid?(data["mediaType"]) -> data["mediaType"]
MIME.valid?(data["mimeType"]) -> data["mimeType"]
true -> nil
is_map(url) && MIME.extensions(url["mediaType"]) != [] ->
url["mediaType"]

is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] ->
data["mediaType"]

is_bitstring(data["mimeType"]) && MIME.extensions(data["mimeType"]) != [] ->
data["mimeType"]

true ->
nil
end end


href = href =
@@ -244,6 +231,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
"type" => Map.get(url || %{}, "type", "Link") "type" => Map.get(url || %{}, "type", "Link")
} }
|> Maps.put_if_present("mediaType", media_type) |> Maps.put_if_present("mediaType", media_type)
|> Maps.put_if_present("width", (url || %{})["width"] || data["width"])
|> Maps.put_if_present("height", (url || %{})["height"] || data["height"])


%{ %{
"url" => [attachment_url], "url" => [attachment_url],
@@ -340,19 +329,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do


def fix_content_map(object), do: object def fix_content_map(object), do: object


def fix_type(object, options \\ [])
defp fix_type(%{"type" => "Note", "inReplyTo" => reply_id, "name" => _} = object, options)
when is_binary(reply_id) do
options = Keyword.put(options, :fetch, true)


def fix_type(%{"inReplyTo" => reply_id, "name" => _} = object, options)
when is_binary(reply_id) do
with true <- Federator.allowed_thread_distance?(options[:depth]),
{:ok, %{data: %{"type" => "Question"} = _} = _} <- get_obj_helper(reply_id, options) do
with %Object{data: %{"type" => "Question"}} <- Object.normalize(reply_id, options) do
Map.put(object, "type", "Answer") Map.put(object, "type", "Answer")
else else
_ -> object _ -> object
end end
end end


def fix_type(object, _), do: object
defp fix_type(object, _options), do: object


# Reduce the object list to find the reported user. # Reduce the object list to find the reported user.
defp get_reported(objects) do defp get_reported(objects) do
@@ -423,10 +411,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# - tags # - tags
# - emoji # - emoji
def handle_incoming( def handle_incoming(
%{"type" => "Create", "object" => %{"type" => objtype} = object} = data,
%{"type" => "Create", "object" => %{"type" => "Page"} = object} = data,
options options
)
when objtype in ~w{Note Page} do
) do
actor = Containment.get_actor(data) actor = Containment.get_actor(data)


with nil <- Activity.get_create_by_object_ap_id(object["id"]), with nil <- Activity.get_create_by_object_ap_id(object["id"]),
@@ -518,14 +505,23 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do


def handle_incoming( def handle_incoming(
%{"type" => "Create", "object" => %{"type" => objtype, "id" => obj_id}} = data, %{"type" => "Create", "object" => %{"type" => objtype, "id" => obj_id}} = data,
_options
options
) )
when objtype in ~w{Question Answer ChatMessage Audio Video Event Article} do
data = Map.put(data, "object", strip_internal_fields(data["object"]))
when objtype in ~w{Question Answer ChatMessage Audio Video Event Article Note} do
fetch_options = Keyword.put(options, :depth, (options[:depth] || 0) + 1)

object =
data["object"]
|> strip_internal_fields()
|> fix_type(fetch_options)
|> fix_in_reply_to(fetch_options)

data = Map.put(data, "object", object)
options = Keyword.put(options, :local, false)


with {:ok, %User{}} <- ObjectValidator.fetch_actor(data), with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
nil <- Activity.get_create_by_object_ap_id(obj_id), nil <- Activity.get_create_by_object_ap_id(obj_id),
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
{:ok, activity, _} <- Pipeline.common_pipeline(data, options) do
{:ok, activity} {:ok, activity}
else else
%Activity{} = activity -> {:ok, activity} %Activity{} = activity -> {:ok, activity}
@@ -949,7 +945,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
object object
|> Map.get("attachment", []) |> Map.get("attachment", [])
|> Enum.map(fn data -> |> Enum.map(fn data ->
[%{"mediaType" => media_type, "href" => href} | _] = data["url"]
[%{"mediaType" => media_type, "href" => href} = url | _] = data["url"]


%{ %{
"url" => href, "url" => href,
@@ -957,6 +953,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
"name" => data["name"], "name" => data["name"],
"type" => "Document" "type" => "Document"
} }
|> Maps.put_if_present("width", url["width"])
|> Maps.put_if_present("height", url["height"])
|> Maps.put_if_present("blurhash", data["blurhash"])
end) end)


Map.put(object, "attachment", attachments) Map.put(object, "attachment", attachments)


+ 9
- 5
lib/pleroma/web/activity_pub/utils.ex Dosyayı Görüntüle

@@ -12,7 +12,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.AdminAPI.AccountView
@@ -38,6 +37,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do
@supported_report_states ~w(open closed resolved) @supported_report_states ~w(open closed resolved)
@valid_visibilities ~w(public unlisted private direct) @valid_visibilities ~w(public unlisted private direct)


def as_local_public, do: Endpoint.url() <> "/#Public"

# Some implementations send the actor URI as the actor field, others send the entire actor object, # Some implementations send the actor URI as the actor field, others send the entire actor object,
# so figure out what the actor's URI is based on what we have. # so figure out what the actor's URI is based on what we have.
def get_ap_id(%{"id" => id} = _), do: id def get_ap_id(%{"id" => id} = _), do: id
@@ -96,8 +97,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
!label_in_collection?(ap_id, params["cc"]) !label_in_collection?(ap_id, params["cc"])


if need_splice? do if need_splice? do
cc_list = extract_list(params["cc"])
Map.put(params, "cc", [ap_id | cc_list])
cc = [ap_id | extract_list(params["cc"])]

params
|> Map.put("cc", cc)
|> Maps.safe_put_in(["object", "cc"], cc)
else else
params params
end end
@@ -107,7 +111,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
%{ %{
"@context" => [ "@context" => [
"https://www.w3.org/ns/activitystreams", "https://www.w3.org/ns/activitystreams",
"#{Web.base_url()}/schemas/litepub-0.1.jsonld",
"#{Endpoint.url()}/schemas/litepub-0.1.jsonld",
%{ %{
"@language" => "und" "@language" => "und"
} }
@@ -132,7 +136,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
end end


def generate_id(type) do def generate_id(type) do
"#{Web.base_url()}/#{type}/#{UUID.generate()}"
"#{Endpoint.url()}/#{type}/#{UUID.generate()}"
end end


def get_notified_from_object(%{"type" => type} = object) when type in @supported_object_types do def get_notified_from_object(%{"type" => type} = object) when type in @supported_object_types do


+ 2
- 1
lib/pleroma/web/activity_pub/views/user_view.ex Dosyayı Görüntüle

@@ -261,7 +261,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do
%{ %{
"id" => featured_address, "id" => featured_address,
"type" => "OrderedCollection", "type" => "OrderedCollection",
"orderedItems" => objects
"orderedItems" => objects,
"totalItems" => length(objects)
} }
|> Map.merge(Utils.make_json_ld_header()) |> Map.merge(Utils.make_json_ld_header())
end end


+ 3
- 3
lib/pleroma/web/activity_pub/visibility.ex Dosyayı Görüntüle

@@ -20,14 +20,14 @@ defmodule Pleroma.Web.ActivityPub.Visibility do


def is_public?(data) do def is_public?(data) do
Utils.label_in_message?(Pleroma.Constants.as_public(), data) or Utils.label_in_message?(Pleroma.Constants.as_public(), data) or
Utils.label_in_message?(Pleroma.Constants.as_local_public(), data)
Utils.label_in_message?(Utils.as_local_public(), data)
end end


def is_local_public?(%Object{data: data}), do: is_local_public?(data) def is_local_public?(%Object{data: data}), do: is_local_public?(data)
def is_local_public?(%Activity{data: data}), do: is_local_public?(data) def is_local_public?(%Activity{data: data}), do: is_local_public?(data)


def is_local_public?(data) do def is_local_public?(data) do
Utils.label_in_message?(Pleroma.Constants.as_local_public(), data) and
Utils.label_in_message?(Utils.as_local_public(), data) and
not Utils.label_in_message?(Pleroma.Constants.as_public(), data) not Utils.label_in_message?(Pleroma.Constants.as_public(), data)
end end


@@ -127,7 +127,7 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
Pleroma.Constants.as_public() in cc -> Pleroma.Constants.as_public() in cc ->
"unlisted" "unlisted"


Pleroma.Constants.as_local_public() in to ->
Utils.as_local_public() in to ->
"local" "local"


# this should use the sql for the object's activity # this should use the sql for the object's activity


+ 0
- 1
lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex Dosyayı Görüntüle

@@ -13,7 +13,6 @@ defmodule Pleroma.Web.AdminAPI.OAuthAppController do
require Logger require Logger


plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(:put_view, Pleroma.Web.MastodonAPI.AppView)


plug( plug(
OAuthScopesPlug, OAuthScopesPlug,


+ 10
- 0
lib/pleroma/web/admin_api/views/o_auth_app_view.ex Dosyayı Görüntüle

@@ -0,0 +1,10 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Web.AdminAPI.OAuthAppView do
use Pleroma.Web, :view
alias Pleroma.Web.MastodonAPI

def render(view, opts), do: MastodonAPI.AppView.render(view, opts)
end

+ 1
- 0
lib/pleroma/web/api_spec/operations/media_operation.ex Dosyayı Görüntüle

@@ -105,6 +105,7 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do
responses: %{ responses: %{
200 => Operation.response("Media", "application/json", Attachment), 200 => Operation.response("Media", "application/json", Attachment),
401 => Operation.response("Media", "application/json", ApiError), 401 => Operation.response("Media", "application/json", ApiError),
403 => Operation.response("Media", "application/json", ApiError),
422 => Operation.response("Media", "application/json", ApiError) 422 => Operation.response("Media", "application/json", ApiError)
} }
} }


+ 2
- 1
lib/pleroma/web/api_spec/operations/timeline_operation.ex Dosyayı Görüntüle

@@ -115,7 +115,8 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
], ],
operationId: "TimelineController.hashtag", operationId: "TimelineController.hashtag",
responses: %{ responses: %{
200 => Operation.response("Array of Status", "application/json", array_of_statuses())
200 => Operation.response("Array of Status", "application/json", array_of_statuses()),
401 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end


+ 219
- 0
lib/pleroma/web/api_spec/operations/twitter_util_operation.ex Dosyayı Görüntüle

@@ -0,0 +1,219 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike

def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end

def emoji_operation do
%Operation{
tags: ["Emojis"],
summary: "List all custom emojis",
operationId: "UtilController.emoji",
parameters: [],
responses: %{
200 =>
Operation.response("List", "application/json", %Schema{
type: :object,
additionalProperties: %Schema{
type: :object,
properties: %{
image_url: %Schema{type: :string},
tags: %Schema{type: :array, items: %Schema{type: :string}}
}
},
example: %{
"firefox" => %{
"image_url" => "/emoji/firefox.png",
"tag" => ["Fun"]
}
}
})
}
}
end

def frontend_configurations_operation do
%Operation{
tags: ["Configuration"],
summary: "Dump frontend configurations",
operationId: "UtilController.frontend_configurations",
parameters: [],
responses: %{
200 =>
Operation.response("List", "application/json", %Schema{
type: :object,
additionalProperties: %Schema{type: :object}
})
}
}
end

def change_password_operation do
%Operation{
tags: ["Account credentials"],
summary: "Change account password",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.change_password",
parameters: [
Operation.parameter(:password, :query, :string, "Current password", required: true),
Operation.parameter(:new_password, :query, :string, "New password", required: true),
Operation.parameter(
:new_password_confirmation,
:query,
:string,
"New password, confirmation",
required: true
)
],
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
400 => Operation.response("Error", "application/json", ApiError),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end

def change_email_operation do
%Operation{
tags: ["Account credentials"],
summary: "Change account email",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.change_email",
parameters: [
Operation.parameter(:password, :query, :string, "Current password", required: true),
Operation.parameter(:email, :query, :string, "New email", required: true)
],
requestBody: nil,
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
400 => Operation.response("Error", "application/json", ApiError),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end

def update_notificaton_settings_operation do
%Operation{
tags: ["Accounts"],
summary: "Update Notification Settings",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.update_notificaton_settings",
parameters: [
Operation.parameter(
:block_from_strangers,
:query,
BooleanLike,
"blocks notifications from accounts you do not follow"
),
Operation.parameter(
:hide_notification_contents,
:query,
BooleanLike,
"removes the contents of a message from the push notification"
)
],
requestBody: nil,
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
400 => Operation.response("Error", "application/json", ApiError)
}
}
end

def disable_account_operation do
%Operation{
tags: ["Account credentials"],
summary: "Disable Account",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.disable_account",
parameters: [
Operation.parameter(:password, :query, :string, "Password")
],
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end

def delete_account_operation do
%Operation{
tags: ["Account credentials"],
summary: "Delete Account",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.delete_account",
parameters: [
Operation.parameter(:password, :query, :string, "Password")
],
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end

def captcha_operation do
%Operation{
summary: "Get a captcha",
operationId: "UtilController.captcha",
parameters: [],
responses: %{
200 => Operation.response("Success", "application/json", %Schema{type: :object})
}
}
end

def healthcheck_operation do
%Operation{
tags: ["Accounts"],
summary: "Quick status check on the instance",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.healthcheck",
parameters: [],
responses: %{
200 => Operation.response("Healthy", "application/json", %Schema{type: :object}),
503 =>
Operation.response("Disabled or Unhealthy", "application/json", %Schema{type: :object})
}
}
end

def remote_subscribe_operation do
%Operation{
tags: ["Accounts"],
summary: "Remote Subscribe",
operationId: "UtilController.remote_subscribe",
parameters: [],
responses: %{200 => Operation.response("Web Page", "test/html", %Schema{type: :string})}
}
end
end

+ 1
- 0
lib/pleroma/web/api_spec/operations/user_import_operation.ex Dosyayı Görüntüle

@@ -23,6 +23,7 @@ defmodule Pleroma.Web.ApiSpec.UserImportOperation do
requestBody: request_body("Parameters", import_request(), required: true), requestBody: request_body("Parameters", import_request(), required: true),
responses: %{ responses: %{
200 => ok_response(), 200 => ok_response(),
403 => Operation.response("Error", "application/json", ApiError),
500 => Operation.response("Error", "application/json", ApiError) 500 => Operation.response("Error", "application/json", ApiError)
}, },
security: [%{"oAuth" => ["write:follow"]}] security: [%{"oAuth" => ["write:follow"]}]


+ 2
- 2
lib/pleroma/web/channels/user_socket.ex Dosyayı Görüntüle

@@ -8,7 +8,7 @@ defmodule Pleroma.Web.UserSocket do


## Channels ## Channels
# channel "room:*", Pleroma.Web.RoomChannel # channel "room:*", Pleroma.Web.RoomChannel
channel("chat:*", Pleroma.Web.ChatChannel)
channel("chat:*", Pleroma.Web.ShoutChannel)


# Socket params are passed from the client and can # Socket params are passed from the client and can
# be used to verify and authenticate a user. After # be used to verify and authenticate a user. After
@@ -22,7 +22,7 @@ defmodule Pleroma.Web.UserSocket do
# See `Phoenix.Token` documentation for examples in # See `Phoenix.Token` documentation for examples in
# performing token verification on connect. # performing token verification on connect.
def connect(%{"token" => token}, socket) do def connect(%{"token" => token}, socket) do
with true <- Pleroma.Config.get([:chat, :enabled]),
with true <- Pleroma.Config.get([:shout, :enabled]),
{:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84_600), {:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84_600),
%User{} = user <- Pleroma.User.get_cached_by_id(user_id) do %User{} = user <- Pleroma.User.get_cached_by_id(user_id) do
{:ok, assign(socket, :user_name, user.nickname)} {:ok, assign(socket, :user_name, user.nickname)}


+ 1
- 1
lib/pleroma/web/common_api/utils.ex Dosyayı Görüntüle

@@ -69,7 +69,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
to = to =
case visibility do case visibility do
"public" -> [Pleroma.Constants.as_public() | draft.mentions] "public" -> [Pleroma.Constants.as_public() | draft.mentions]
"local" -> [Pleroma.Constants.as_local_public() | draft.mentions]
"local" -> [Utils.as_local_public() | draft.mentions]
end end


cc = [draft.user.follower_address] cc = [draft.user.follower_address]


+ 1
- 1
lib/pleroma/web/endpoint.ex Dosyayı Görüntüle

@@ -102,7 +102,7 @@ defmodule Pleroma.Web.Endpoint do
plug(Plug.Parsers, plug(Plug.Parsers,
parsers: [ parsers: [
:urlencoded, :urlencoded,
{:multipart, length: {Config, :get, [[:instance, :upload_limit]]}},
{:multipart, length: Config.get([:instance, :upload_limit])},
:json :json
], ],
pass: ["*/*"], pass: ["*/*"],


+ 5
- 0
lib/pleroma/web/federator.ex Dosyayı Görüntüle

@@ -96,6 +96,11 @@ defmodule Pleroma.Web.Federator do
Logger.debug("Unhandled actor #{actor}, #{inspect(e)}") Logger.debug("Unhandled actor #{actor}, #{inspect(e)}")
{:error, e} {:error, e}


{:error, {:validate_object, _}} = e ->
Logger.error("Incoming AP doc validation error: #{inspect(e)}")
Logger.debug(Jason.encode!(params, pretty: true))
e

e -> e ->
# Just drop those for now # Just drop those for now
Logger.debug(fn -> "Unhandled activity\n" <> Jason.encode!(params, pretty: true) end) Logger.debug(fn -> "Unhandled activity\n" <> Jason.encode!(params, pretty: true) end)


+ 2
- 2
lib/pleroma/web/feed/feed_view.ex Dosyayı Görüntüle

@@ -52,10 +52,10 @@ defmodule Pleroma.Web.Feed.FeedView do
def feed_logo do def feed_logo do
case Pleroma.Config.get([:feed, :logo]) do case Pleroma.Config.get([:feed, :logo]) do
nil -> nil ->
"#{Pleroma.Web.base_url()}/static/logo.svg"
"#{Pleroma.Web.Endpoint.url()}/static/logo.svg"


logo -> logo ->
"#{Pleroma.Web.base_url()}#{logo}"
"#{Pleroma.Web.Endpoint.url()}#{logo}"
end end
|> MediaProxy.url() |> MediaProxy.url()
end end


+ 1
- 1
lib/pleroma/web/feed/user_controller.ex Dosyayı Görüntüle

@@ -28,7 +28,7 @@ defmodule Pleroma.Web.Feed.UserController do


def feed_redirect(conn, %{"nickname" => nickname}) do def feed_redirect(conn, %{"nickname" => nickname}) do
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
redirect(conn, external: "#{user_feed_url(conn, :feed, user.nickname)}.atom")
redirect(conn, external: "#{Routes.user_feed_url(conn, :feed, user.nickname)}.atom")
end end
end end




+ 2
- 2
lib/pleroma/web/mastodon_api/controllers/auth_controller.ex Dosyayı Görüntüle

@@ -53,7 +53,7 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
defp redirect_to_oauth_form(conn, _params) do defp redirect_to_oauth_form(conn, _params) do
with {:ok, app} <- local_mastofe_app() do with {:ok, app} <- local_mastofe_app() do
path = path =
o_auth_path(conn, :authorize,
Routes.o_auth_path(conn, :authorize,
response_type: "code", response_type: "code",
client_id: app.client_id, client_id: app.client_id,
redirect_uri: ".", redirect_uri: ".",
@@ -90,7 +90,7 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
defp local_mastodon_post_login_path(conn) do defp local_mastodon_post_login_path(conn) do
case get_session(conn, :return_to) do case get_session(conn, :return_to) do
nil -> nil ->
masto_fe_path(conn, :index, ["getting-started"])
Routes.masto_fe_path(conn, :index, ["getting-started"])


return_to -> return_to ->
delete_session(conn, :return_to) delete_session(conn, :return_to)


+ 0
- 1
lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex Dosyayı Görüntüle

@@ -9,7 +9,6 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestController do
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug


plug(:put_view, Pleroma.Web.MastodonAPI.AccountView)
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(:assign_follower when action != :index) plug(:assign_follower when action != :index)




+ 0
- 1
lib/pleroma/web/mastodon_api/controllers/media_controller.ex Dosyayı Görüntüle

@@ -13,7 +13,6 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do
action_fallback(Pleroma.Web.MastodonAPI.FallbackController) action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
plug(Majic.Plug, [pool: Pleroma.MajicPool] when action in [:create, :create2]) plug(Majic.Plug, [pool: Pleroma.MajicPool] when action in [:create, :create2])
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)


plug(OAuthScopesPlug, %{scopes: ["read:media"]} when action == :show) plug(OAuthScopesPlug, %{scopes: ["read:media"]} when action == :show)
plug(OAuthScopesPlug, %{scopes: ["write:media"]} when action != :show) plug(OAuthScopesPlug, %{scopes: ["write:media"]} when action != :show)


+ 2
- 2
lib/pleroma/web/mastodon_api/controllers/search_controller.ex Dosyayı Görüntüle

@@ -8,8 +8,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.ControllerHelper alias Pleroma.Web.ControllerHelper
alias Pleroma.Web.Endpoint
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
@@ -108,7 +108,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
end end


defp resource_search(:v2, "hashtags", query, options) do defp resource_search(:v2, "hashtags", query, options) do
tags_path = Web.base_url() <> "/tag/"
tags_path = Endpoint.url() <> "/tag/"


query query
|> prepare_tags(options) |> prepare_tags(options)


+ 0
- 2
lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex Dosyayı Görüntüle

@@ -37,8 +37,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
when action in [:public, :hashtag] when action in [:public, :hashtag]
) )


plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)

defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TimelineOperation defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TimelineOperation


# GET /api/v1/timelines/home # GET /api/v1/timelines/home


+ 11
- 0
lib/pleroma/web/mastodon_api/views/account_view.ex Dosyayı Görüntüle

@@ -292,6 +292,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|> maybe_put_allow_following_move(user, opts[:for]) |> maybe_put_allow_following_move(user, opts[:for])
|> maybe_put_unread_conversation_count(user, opts[:for]) |> maybe_put_unread_conversation_count(user, opts[:for])
|> maybe_put_unread_notification_count(user, opts[:for]) |> maybe_put_unread_notification_count(user, opts[:for])
|> maybe_put_email_address(user, opts[:for])
end end


defp username_from_nickname(string) when is_binary(string) do defp username_from_nickname(string) when is_binary(string) do
@@ -403,6 +404,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do


defp maybe_put_unread_notification_count(data, _, _), do: data defp maybe_put_unread_notification_count(data, _, _), do: data


defp maybe_put_email_address(data, %User{id: user_id}, %User{id: user_id} = user) do
Kernel.put_in(
data,
[:pleroma, :email],
user.email
)
end

defp maybe_put_email_address(data, _, _), do: data

defp image_url(%{"url" => [%{"href" => href} | _]}), do: href defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
defp image_url(_), do: nil defp image_url(_), do: nil
end end

+ 2
- 2
lib/pleroma/web/mastodon_api/views/custom_emoji_view.ex Dosyayı Görüntüle

@@ -6,14 +6,14 @@ defmodule Pleroma.Web.MastodonAPI.CustomEmojiView do
use Pleroma.Web, :view use Pleroma.Web, :view


alias Pleroma.Emoji alias Pleroma.Emoji
alias Pleroma.Web
alias Pleroma.Web.Endpoint


def render("index.json", %{custom_emojis: custom_emojis}) do def render("index.json", %{custom_emojis: custom_emojis}) do
render_many(custom_emojis, __MODULE__, "show.json") render_many(custom_emojis, __MODULE__, "show.json")
end end


def render("show.json", %{custom_emoji: {shortcode, %Emoji{file: relative_url, tags: tags}}}) do def render("show.json", %{custom_emoji: {shortcode, %Emoji{file: relative_url, tags: tags}}}) do
url = Web.base_url() |> URI.merge(relative_url) |> to_string()
url = Endpoint.url() |> URI.merge(relative_url) |> to_string()


%{ %{
"shortcode" => shortcode, "shortcode" => shortcode,


+ 10
- 0
lib/pleroma/web/mastodon_api/views/follow_request_view.ex Dosyayı Görüntüle

@@ -0,0 +1,10 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Web.MastodonAPI.FollowRequestView do
use Pleroma.Web, :view
alias Pleroma.Web.MastodonAPI

def render(view, opts), do: MastodonAPI.AccountView.render(view, opts)
end

+ 10
- 5
lib/pleroma/web/mastodon_api/views/instance_view.ex Dosyayı Görüntüle

@@ -14,7 +14,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
instance = Config.get(:instance) instance = Config.get(:instance)


%{ %{
uri: Pleroma.Web.base_url(),
uri: Pleroma.Web.Endpoint.url(),
title: Keyword.get(instance, :name), title: Keyword.get(instance, :name),
description: Keyword.get(instance, :description), description: Keyword.get(instance, :description),
version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})", version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})",
@@ -24,7 +24,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
}, },
stats: Pleroma.Stats.get_stats(), stats: Pleroma.Stats.get_stats(),
thumbnail: thumbnail:
URI.merge(Pleroma.Web.base_url(), Keyword.get(instance, :instance_thumbnail)) |> to_string,
URI.merge(Pleroma.Web.Endpoint.url(), Keyword.get(instance, :instance_thumbnail))
|> to_string,
languages: ["en"], languages: ["en"],
registrations: Keyword.get(instance, :registrations_open), registrations: Keyword.get(instance, :registrations_open),
approval_required: Keyword.get(instance, :account_approval_required), approval_required: Keyword.get(instance, :account_approval_required),
@@ -35,8 +36,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
avatar_upload_limit: Keyword.get(instance, :avatar_upload_limit), avatar_upload_limit: Keyword.get(instance, :avatar_upload_limit),
background_upload_limit: Keyword.get(instance, :background_upload_limit), background_upload_limit: Keyword.get(instance, :background_upload_limit),
banner_upload_limit: Keyword.get(instance, :banner_upload_limit), banner_upload_limit: Keyword.get(instance, :banner_upload_limit),
background_image: Pleroma.Web.base_url() <> Keyword.get(instance, :background_image),
chat_limit: Keyword.get(instance, :chat_limit),
background_image: Pleroma.Web.Endpoint.url() <> Keyword.get(instance, :background_image),
shout_limit: Config.get([:shout, :limit]),
description_limit: Keyword.get(instance, :description_limit), description_limit: Keyword.get(instance, :description_limit),
pleroma: %{ pleroma: %{
metadata: %{ metadata: %{
@@ -68,9 +69,13 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
if Config.get([:gopher, :enabled]) do if Config.get([:gopher, :enabled]) do
"gopher" "gopher"
end, end,
if Config.get([:chat, :enabled]) do
# backwards compat
if Config.get([:shout, :enabled]) do
"chat" "chat"
end, end,
if Config.get([:shout, :enabled]) do
"shout"
end,
if Config.get([:instance, :allow_relay]) do if Config.get([:instance, :allow_relay]) do
"relay" "relay"
end, end,


Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor

Yükleniyor…
İptal
Kaydet