Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop

This commit is contained in:
sadposter 2021-02-20 15:27:56 +00:00
commit 5f33699169
383 changed files with 5878 additions and 3203 deletions

View file

@ -34,6 +34,14 @@ build:
- mix deps.get - mix deps.get
- mix compile --force - mix compile --force
spec-build:
stage: test
artifacts:
paths:
- spec.json
script:
- mix pleroma.openapi_spec spec.json
benchmark: benchmark:
stage: benchmark stage: benchmark
when: manual when: manual
@ -155,6 +163,20 @@ review_app:
- (ssh -t dokku@pleroma.online -- certs:add "$CI_ENVIRONMENT_SLUG" /home/dokku/server.crt /home/dokku/server.key) || true - (ssh -t dokku@pleroma.online -- certs:add "$CI_ENVIRONMENT_SLUG" /home/dokku/server.crt /home/dokku/server.key) || true
- git push -f dokku@pleroma.online:$CI_ENVIRONMENT_SLUG $CI_COMMIT_SHA:refs/heads/master - git push -f dokku@pleroma.online:$CI_ENVIRONMENT_SLUG $CI_COMMIT_SHA:refs/heads/master
spec-deploy:
stage: deploy
artifacts:
paths:
- spec.json
only:
- develop@pleroma/pleroma
image: alpine:latest
before_script:
- apk add curl
script:
- curl -X POST -F"token=$API_DOCS_PIPELINE_TRIGGER" -F'ref=master' -F"variables[BRANCH]=$CI_COMMIT_REF_NAME" -F"variables[JOB_REF]=$CI_JOB_ID" https://git.pleroma.social/api/v4/projects/1130/trigger/pipeline
stop_review_app: stop_review_app:
image: alpine:3.9 image: alpine:3.9
stage: deploy stage: deploy
@ -349,3 +371,26 @@ docker-release:
- dind - dind
only: only:
- /^release/.*$/@pleroma/pleroma - /^release/.*$/@pleroma/pleroma
docker-adhoc:
stage: docker
image: docker:latest
cache: {}
dependencies: []
variables: *docker-variables
before_script: *before-docker
allow_failure: true
script:
script:
- mkdir -p /root/.docker/cli-plugins
- wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
- echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
- chmod +x ~/.docker/cli-plugins/docker-buildx
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- docker buildx create --name mbuilder --driver docker-container --use
- docker buildx inspect --bootstrap
- docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
tags:
- dind
only:
- /^build-docker/.*$/@pleroma/pleroma

View file

@ -1,2 +1,3 @@
Ariadne Conill <ariadne@dereferenced.org> <nenolod@dereferenced.org> Ariadne Conill <ariadne@dereferenced.org> <nenolod@dereferenced.org>
Ariadne Conill <ariadne@dereferenced.org> <nenolod@gmail.com> Ariadne Conill <ariadne@dereferenced.org> <nenolod@gmail.com>
rinpatch <rin@patch.cx> <rinpatch@sdf.org>

View file

@ -6,18 +6,39 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased ## Unreleased
### Removed
- `:auth, :enforce_oauth_admin_scope_usage` configuration option.
### Changed ### Changed
- **Breaking:** Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm` - **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed` - **Breaking**: Changed `mix pleroma.user toggle_activated` to `mix pleroma.user activate/deactivate`
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
- Polls now always return a `voters_count`, even if they are single-choice. - Polls now always return a `voters_count`, even if they are single-choice.
- Admin Emails: The ap id is used as the user link in emails now. - Admin Emails: The ap id is used as the user link in emails now.
- Improved registration workflow for email confirmation and account approval modes. - Improved registration workflow for email confirmation and account approval modes.
- Search: When using Postgres 11+, Pleroma will use the `websearch_to_tsvector` function to parse search queries. - Search: When using Postgres 11+, Pleroma will use the `websearch_to_tsvector` function to parse search queries.
- Emoji: Support the full Unicode 13.1 set of Emoji for reactions, plus regional indicators. - Emoji: Support the full Unicode 13.1 set of Emoji for reactions, plus regional indicators.
- Admin API: Reports now ordered by newest
- Deprecated `Pleroma.Uploaders.S3, :public_endpoint`. Now `Pleroma.Upload, :base_url` is the standard configuration key for all uploaders. - Deprecated `Pleroma.Uploaders.S3, :public_endpoint`. Now `Pleroma.Upload, :base_url` is the standard configuration key for all uploaders.
- Improved Apache webserver support: updated sample configuration, MediaProxy cache invalidation verified with the included sample script
- Improve OAuth 2.0 provider support. A missing `fqn` field was added to the response, but does not expose the user's email address.
- Provide redirect of external posts from `/notice/:id` to their original URL
- Admins no longer receive notifications for reports if they are the actor making the report.
- Improved Mailer configuration setting descriptions for AdminFE.
- Updated default avatar to look nicer.
<details>
<summary>API Changes</summary>
- **Breaking:** AdminAPI changed User field `confirmation_pending` to `is_confirmed`
- **Breaking:** AdminAPI changed User field `approval_pending` to `is_approved`
- **Breaking**: AdminAPI changed User field `deactivated` to `is_active`
- **Breaking:** AdminAPI `GET /api/pleroma/admin/users/:nickname_or_id/statuses` changed response format and added the number of total users posts.
- **Breaking:** AdminAPI `GET /api/pleroma/admin/instances/:instance/statuses` changed response format and added the number of total users posts.
- Admin API: Reports now ordered by newest
- Pleroma API: `GET /api/v1/pleroma/chats` is deprecated in favor of `GET /api/v2/pleroma/chats`.
</details>
### Added ### Added
@ -35,17 +56,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- OAuth improvements and fixes: more secure session-based authentication (by token that could be revoked anytime), ability to revoke belonging OAuth token from any client etc. - OAuth improvements and fixes: more secure session-based authentication (by token that could be revoked anytime), ability to revoke belonging OAuth token from any client etc.
- Ability to set ActivityPub aliases for follower migration. - Ability to set ActivityPub aliases for follower migration.
- Configurable background job limits for RichMedia (link previews) and MediaProxyWarmingPolicy - Configurable background job limits for RichMedia (link previews) and MediaProxyWarmingPolicy
- Ability to define custom HTTP headers per each frontend
- MRF (`NoEmptyPolicy`): New MRF Policy which will deny empty statuses or statuses of only mentions from being created by local users
- New users will receive a simple email confirming their registration if no other emails will be dispatched. (e.g., Welcome, Confirmation, or Approval Required)
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
- Admin API: (`GET /api/pleroma/admin/users`) filter users by `unconfirmed` status and `actor_type`. - Admin API: (`GET /api/pleroma/admin/users`) filter users by `unconfirmed` status and `actor_type`.
- Pleroma API: `GET /api/v2/pleroma/chats` added. It is exactly like `GET /api/v1/pleroma/chats` except supports pagination.
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending. - Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances. - Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute. - Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
- Admin API: An endpoint to manage frontends. - Admin API: An endpoint to manage frontends.
- Streaming API: Add follow relationships updates. - Streaming API: Add follow relationships updates.
- WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types - WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types.
- Mastodon API: Add monthly active users to `/api/v1/instance` (`pleroma.stats.mau`).
- Mastodon API: Home, public, hashtag & list timelines accept `only_media`, `remote` & `local` parameters for filtration.
- Mastodon API: `/api/v1/accounts/:id` & `/api/v1/mutes` endpoints accept `with_relationships` parameter and return filled `pleroma.relationship` field.
- Mastodon API: Endpoint to remove a conversation (`DELETE /api/v1/conversations/:id`).
</details> </details>
### Fixed ### Fixed
@ -55,11 +83,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Creating incorrect IPv4 address-style HTTP links when encountering certain numbers. - Creating incorrect IPv4 address-style HTTP links when encountering certain numbers.
- Reblog API Endpoint: Do not set visibility parameter to public by default and let CommonAPI to infer it from status, so a user can reblog their private status without explicitly setting reblog visibility to private. - Reblog API Endpoint: Do not set visibility parameter to public by default and let CommonAPI to infer it from status, so a user can reblog their private status without explicitly setting reblog visibility to private.
- Tag URLs in statuses are now absolute - Tag URLs in statuses are now absolute
- Removed duplicate jobs to purge expired activities
- File extensions of some attachments were incorrectly changed. This feature has been disabled for now.
- Mix task pleroma.instance creates missing parent directories if the configuration or SQL output paths are changed.
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
- Mastodon API: Current user is now included in conversation if it's the only participant. - Mastodon API: Current user is now included in conversation if it's the only participant.
- Mastodon API: Fixed last_status.account being not filled with account data. - Mastodon API: Fixed last_status.account being not filled with account data.
- Mastodon API: Fix not being able to add or remove multiple users at once in lists.
- Mastodon API: Fixed own_votes being not returned with poll data.
- Mastodon API: Fixed creation of scheduled posts with polls.
- Mastodon API: Support for expires_in/expires_at in the Filters.
</details> </details>
## Unreleased (Patch) ## Unreleased (Patch)

View file

@ -5,6 +5,13 @@ copy of the license file as AGPL-3.
--- ---
Files inside docs directory are copyright © 2021 Pleroma Authors
<https://pleroma.social/>, and are distributed under the Creative Commons
Attribution 4.0 International license, you should have received
a copy of the license file as CC-BY-4.0.
---
The following files are copyright © 2019 shitposter.club, and are distributed The following files are copyright © 2019 shitposter.club, and are distributed
under the Creative Commons Attribution-ShareAlike 4.0 International license, under the Creative Commons Attribution-ShareAlike 4.0 International license,
you should have received a copy of the license file as CC-BY-SA-4.0. you should have received a copy of the license file as CC-BY-SA-4.0.

View file

@ -33,10 +33,11 @@ defmodule Pleroma.LoadTesting.Fetcher do
end end
defp create_filter(user) do defp create_filter(user) do
Pleroma.Filter.create(%Pleroma.Filter{ Pleroma.Filter.create(%{
user_id: user.id, user_id: user.id,
phrase: "must be filtered", phrase: "must be filtered",
hide: true hide: true,
context: ["home"]
}) })
end end

View file

@ -441,7 +441,9 @@ config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
headers: [], headers: [],
options: [] options: []
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script, script_path: nil config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script,
script_path: nil,
url_format: nil
# Note: media preview proxy depends on media proxy to be enabled # Note: media preview proxy depends on media proxy to be enabled
config :pleroma, :media_preview_proxy, config :pleroma, :media_preview_proxy,
@ -544,6 +546,7 @@ config :pleroma, Oban,
queues: [ queues: [
activity_expiration: 10, activity_expiration: 10,
token_expiration: 5, token_expiration: 5,
filter_expiration: 1,
backup: 1, backup: 1,
federator_incoming: 50, federator_incoming: 50,
federator_outgoing: 50, federator_outgoing: 50,
@ -611,10 +614,7 @@ config :ueberauth,
base_path: "/oauth", base_path: "/oauth",
providers: ueberauth_providers providers: ueberauth_providers
config :pleroma, config :pleroma, :auth, oauth_consumer_strategies: oauth_consumer_strategies
:auth,
enforce_oauth_admin_scope_usage: true,
oauth_consumer_strategies: oauth_consumer_strategies
config :pleroma, Pleroma.Emails.Mailer, adapter: Swoosh.Adapters.Sendmail, enabled: false config :pleroma, Pleroma.Emails.Mailer, adapter: Swoosh.Adapters.Sendmail, enabled: false
@ -726,7 +726,10 @@ config :pleroma, :frontends,
"git" => "https://git.pleroma.social/pleroma/fedi-fe", "git" => "https://git.pleroma.social/pleroma/fedi-fe",
"build_url" => "build_url" =>
"https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build", "https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build",
"ref" => "master" "ref" => "master",
"custom-http-headers" => [
{"service-worker-allowed", "/"}
]
}, },
"admin-fe" => %{ "admin-fe" => %{
"name" => "admin-fe", "name" => "admin-fe",

View file

@ -60,6 +60,12 @@ frontend_options = [
label: "Build directory", label: "Build directory",
type: :string, type: :string,
description: "The directory inside the zip file " description: "The directory inside the zip file "
},
%{
key: "custom-http-headers",
label: "Custom HTTP headers",
type: {:list, :string},
description: "The custom HTTP headers for the frontend"
} }
] ]
@ -93,7 +99,8 @@ config :pleroma, :config_description, [
key: :base_url, key: :base_url,
label: "Base URL", label: "Base URL",
type: :string, type: :string,
description: "Base URL for the uploads, needed if you use CDN", description:
"Base URL for the uploads. Required if you use a CDN or host attachments under a different domain.",
suggestions: [ suggestions: [
"https://cdn-host.com" "https://cdn-host.com"
] ]
@ -208,253 +215,216 @@ config :pleroma, :config_description, [
type: :group, type: :group,
description: "Mailer-related settings", description: "Mailer-related settings",
children: [ children: [
%{
key: :enabled,
label: "Mailer Enabled",
type: :boolean
},
%{ %{
key: :adapter, key: :adapter,
type: :module, type: :module,
description: description:
"One of the mail adapters listed in [Swoosh readme](https://github.com/swoosh/swoosh#adapters)," <> "One of the mail adapters listed in [Swoosh documentation](https://hexdocs.pm/swoosh/Swoosh.html#module-adapters)",
" or Swoosh.Adapters.Local for in-memory mailbox",
suggestions: [ suggestions: [
Swoosh.Adapters.AmazonSES,
Swoosh.Adapters.Dyn,
Swoosh.Adapters.Gmail,
Swoosh.Adapters.Mailgun,
Swoosh.Adapters.Mailjet,
Swoosh.Adapters.Mandrill,
Swoosh.Adapters.Postmark,
Swoosh.Adapters.SMTP, Swoosh.Adapters.SMTP,
Swoosh.Adapters.Sendgrid, Swoosh.Adapters.Sendgrid,
Swoosh.Adapters.Sendmail, Swoosh.Adapters.Sendmail,
Swoosh.Adapters.Mandrill,
Swoosh.Adapters.Mailgun,
Swoosh.Adapters.Mailjet,
Swoosh.Adapters.Postmark,
Swoosh.Adapters.SparkPost,
Swoosh.Adapters.AmazonSES,
Swoosh.Adapters.Dyn,
Swoosh.Adapters.SocketLabs, Swoosh.Adapters.SocketLabs,
Swoosh.Adapters.Gmail, Swoosh.Adapters.SparkPost
Swoosh.Adapters.Local
] ]
}, },
%{
key: :enabled,
type: :boolean,
description: "Allow/disallow send emails"
},
%{ %{
group: {:subgroup, Swoosh.Adapters.SMTP}, group: {:subgroup, Swoosh.Adapters.SMTP},
key: :relay, key: :relay,
type: :string, type: :string,
description: "`Swoosh.Adapters.SMTP` adapter specific setting", description: "Hostname or IP address",
suggestions: ["smtp.gmail.com"] suggestions: ["smtp.example.com"]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :username,
type: :string,
description: "`Swoosh.Adapters.SMTP` adapter specific setting",
suggestions: ["pleroma"]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :password,
type: :string,
description: "`Swoosh.Adapters.SMTP` adapter specific setting",
suggestions: ["password"]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :ssl,
label: "SSL",
type: :boolean,
description: "`Swoosh.Adapters.SMTP` adapter specific setting"
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :tls,
label: "TLS",
type: :atom,
description: "`Swoosh.Adapters.SMTP` adapter specific setting",
suggestions: [:always, :never, :if_available]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :auth,
type: :atom,
description: "`Swoosh.Adapters.SMTP` adapter specific setting",
suggestions: [:always, :never, :if_available]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.SMTP}, group: {:subgroup, Swoosh.Adapters.SMTP},
key: :port, key: :port,
type: :integer, type: :integer,
description: "`Swoosh.Adapters.SMTP` adapter specific setting", description: "SMTP port",
suggestions: [1025] suggestions: ["1025"]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :username,
type: :string,
description: "SMTP AUTH username",
suggestions: ["user@example.com"]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :password,
type: :string,
description: "SMTP AUTH password",
suggestions: ["password"]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :ssl,
label: "Use SSL",
type: :boolean,
description: "Use Implicit SSL/TLS. e.g. port 465"
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :tls,
label: "STARTTLS Mode",
type: {:dropdown, :atom},
description: "Explicit TLS (STARTTLS) enforcement mode",
suggestions: [:if_available, :always, :never]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :auth,
label: "AUTH Mode",
type: {:dropdown, :atom},
description: "SMTP AUTH enforcement mode",
suggestions: [:if_available, :always, :never]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.SMTP}, group: {:subgroup, Swoosh.Adapters.SMTP},
key: :retries, key: :retries,
type: :integer, type: :integer,
description: "`Swoosh.Adapters.SMTP` adapter specific setting", description: "SMTP temporary (4xx) error retries",
suggestions: [5] suggestions: [1]
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :no_mx_lookups,
label: "No MX lookups",
type: :boolean,
description: "`Swoosh.Adapters.SMTP` adapter specific setting"
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Sendgrid}, group: {:subgroup, Swoosh.Adapters.Sendgrid},
key: :api_key, key: :api_key,
label: "API key", label: "SendGrid API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.Sendgrid` adapter specific setting", suggestions: ["YOUR_API_KEY"]
suggestions: ["my-api-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Sendmail}, group: {:subgroup, Swoosh.Adapters.Sendmail},
key: :cmd_path, key: :cmd_path,
type: :string, type: :string,
description: "`Swoosh.Adapters.Sendmail` adapter specific setting",
suggestions: ["/usr/bin/sendmail"] suggestions: ["/usr/bin/sendmail"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Sendmail}, group: {:subgroup, Swoosh.Adapters.Sendmail},
key: :cmd_args, key: :cmd_args,
type: :string, type: :string,
description: "`Swoosh.Adapters.Sendmail` adapter specific setting",
suggestions: ["-N delay,failure,success"] suggestions: ["-N delay,failure,success"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Sendmail}, group: {:subgroup, Swoosh.Adapters.Sendmail},
key: :qmail, key: :qmail,
type: :boolean, label: "Qmail compat mode",
description: "`Swoosh.Adapters.Sendmail` adapter specific setting" type: :boolean
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Mandrill}, group: {:subgroup, Swoosh.Adapters.Mandrill},
key: :api_key, key: :api_key,
label: "API key", label: "Mandrill API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.Mandrill` adapter specific setting", suggestions: ["YOUR_API_KEY"]
suggestions: ["my-api-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Mailgun}, group: {:subgroup, Swoosh.Adapters.Mailgun},
key: :api_key, key: :api_key,
label: "API key", label: "Mailgun API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.Mailgun` adapter specific setting", suggestions: ["YOUR_API_KEY"]
suggestions: ["my-api-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Mailgun}, group: {:subgroup, Swoosh.Adapters.Mailgun},
key: :domain, key: :domain,
type: :string, type: :string,
description: "`Swoosh.Adapters.Mailgun` adapter specific setting", suggestions: ["YOUR_DOMAIN_NAME"]
suggestions: ["pleroma.com"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Mailjet}, group: {:subgroup, Swoosh.Adapters.Mailjet},
key: :api_key, key: :api_key,
label: "API key", label: "MailJet Public API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.Mailjet` adapter specific setting", suggestions: ["MJ_APIKEY_PUBLIC"]
suggestions: ["my-api-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Mailjet}, group: {:subgroup, Swoosh.Adapters.Mailjet},
key: :secret, key: :secret,
label: "MailJet Private API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.Mailjet` adapter specific setting", suggestions: ["MJ_APIKEY_PRIVATE"]
suggestions: ["my-secret-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Postmark}, group: {:subgroup, Swoosh.Adapters.Postmark},
key: :api_key, key: :api_key,
label: "API key", label: "Postmark API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.Postmark` adapter specific setting", suggestions: ["X-Postmark-Server-Token"]
suggestions: ["my-api-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.SparkPost}, group: {:subgroup, Swoosh.Adapters.SparkPost},
key: :api_key, key: :api_key,
label: "API key", label: "SparkPost API key",
type: :string, type: :string,
description: "`Swoosh.Adapters.SparkPost` adapter specific setting", suggestions: ["YOUR_API_KEY"]
suggestions: ["my-api-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.SparkPost}, group: {:subgroup, Swoosh.Adapters.SparkPost},
key: :endpoint, key: :endpoint,
type: :string, type: :string,
description: "`Swoosh.Adapters.SparkPost` adapter specific setting",
suggestions: ["https://api.sparkpost.com/api/v1"] suggestions: ["https://api.sparkpost.com/api/v1"]
}, },
%{
group: {:subgroup, Swoosh.Adapters.AmazonSES},
key: :region,
type: :string,
description: "`Swoosh.Adapters.AmazonSES` adapter specific setting",
suggestions: ["us-east-1", "us-east-2"]
},
%{ %{
group: {:subgroup, Swoosh.Adapters.AmazonSES}, group: {:subgroup, Swoosh.Adapters.AmazonSES},
key: :access_key, key: :access_key,
label: "AWS Access Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.AmazonSES` adapter specific setting", suggestions: ["AWS_ACCESS_KEY"]
suggestions: ["aws-access-key"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.AmazonSES}, group: {:subgroup, Swoosh.Adapters.AmazonSES},
key: :secret, key: :secret,
label: "AWS Secret Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.AmazonSES` adapter specific setting", suggestions: ["AWS_SECRET_KEY"]
suggestions: ["aws-secret-key"] },
%{
group: {:subgroup, Swoosh.Adapters.AmazonSES},
key: :region,
label: "AWS Region",
type: :string,
suggestions: ["us-east-1", "us-east-2"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Dyn}, group: {:subgroup, Swoosh.Adapters.Dyn},
key: :api_key, key: :api_key,
label: "API key", label: "Dyn API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.Dyn` adapter specific setting", suggestions: ["apikey"]
suggestions: ["my-api-key"]
},
%{
group: {:subgroup, Swoosh.Adapters.SocketLabs},
key: :server_id,
type: :string,
description: "`Swoosh.Adapters.SocketLabs` adapter specific setting"
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.SocketLabs}, group: {:subgroup, Swoosh.Adapters.SocketLabs},
key: :api_key, key: :api_key,
label: "API key", label: "SocketLabs API Key",
type: :string, type: :string,
description: "`Swoosh.Adapters.SocketLabs` adapter specific setting" suggestions: ["INJECTION_API_KEY"]
},
%{
group: {:subgroup, Swoosh.Adapters.SocketLabs},
key: :server_id,
label: "Server ID",
type: :string,
suggestions: ["SERVER_ID"]
}, },
%{ %{
group: {:subgroup, Swoosh.Adapters.Gmail}, group: {:subgroup, Swoosh.Adapters.Gmail},
key: :access_token, key: :access_token,
label: "GMail API Access Token",
type: :string, type: :string,
description: "`Swoosh.Adapters.Gmail` adapter specific setting" suggestions: ["GMAIL_API_ACCESS_TOKEN"]
}
]
},
%{
group: :swoosh,
type: :group,
description: "`Swoosh.Adapters.Local` adapter specific settings",
children: [
%{
group: {:subgroup, Swoosh.Adapters.Local},
key: :serve_mailbox,
type: :boolean,
description: "Run the preview server together as part of your app"
},
%{
group: {:subgroup, Swoosh.Adapters.Local},
key: :preview_port,
type: :integer,
description: "The preview server port",
suggestions: [4001]
} }
] ]
}, },
@ -1539,7 +1509,8 @@ config :pleroma, :config_description, [
%{ %{
key: :max_body_length, key: :max_body_length,
type: :integer, type: :integer,
description: "Maximum file size allowed through the Pleroma MediaProxy cache." description:
"Maximum file size (in bytes) allowed through the Pleroma MediaProxy cache."
}, },
%{ %{
key: :max_read_duration, key: :max_read_duration,
@ -1589,7 +1560,7 @@ config :pleroma, :config_description, [
key: :min_content_length, key: :min_content_length,
type: :integer, type: :integer,
description: description:
"Min content length to perform preview, in bytes. If greater than 0, media smaller in size will be served as is, without thumbnailing." "Min content length (in bytes) to perform preview. Media smaller in size will be served without thumbnailing."
} }
] ]
}, },
@ -1627,13 +1598,21 @@ config :pleroma, :config_description, [
group: :pleroma, group: :pleroma,
key: Pleroma.Web.MediaProxy.Invalidation.Script, key: Pleroma.Web.MediaProxy.Invalidation.Script,
type: :group, type: :group,
description: "Script invalidate settings", description: "Invalidation script settings",
children: [ children: [
%{ %{
key: :script_path, key: :script_path,
type: :string, type: :string,
description: "Path to shell script. Which will run purge cache.", description: "Path to executable script which will purge cached items.",
suggestions: ["./installation/nginx-cache-purge.sh.example"] suggestions: ["./installation/nginx-cache-purge.sh.example"]
},
%{
key: :url_format,
label: "URL Format",
type: :string,
description:
"Optional URL format preprocessing. Only required for Apache's htcacheclean.",
suggestions: [":htcacheclean"]
} }
] ]
}, },
@ -2875,7 +2854,7 @@ config :pleroma, :config_description, [
type: :integer, type: :integer,
description: description:
"Activity pub routes (except question activities). Default: `nil` (no expiration).", "Activity pub routes (except question activities). Default: `nil` (no expiration).",
suggestions: [30_000, nil] suggestions: [nil]
}, },
%{ %{
key: :activity_pub_question, key: :activity_pub_question,
@ -3211,6 +3190,12 @@ config :pleroma, :config_description, [
type: :string, type: :string,
description: "S3 host", description: "S3 host",
suggestions: ["s3.eu-central-1.amazonaws.com"] suggestions: ["s3.eu-central-1.amazonaws.com"]
},
%{
key: :region,
type: :string,
description: "S3 region (for AWS)",
suggestions: ["us-east-1"]
} }
] ]
}, },
@ -3307,9 +3292,9 @@ config :pleroma, :config_description, [
}, },
%{ %{
key: :ip_whitelist, key: :ip_whitelist,
label: "IP Whitelist",
type: [{:list, :string}, {:list, :charlist}, {:list, :tuple}], type: [{:list, :string}, {:list, :charlist}, {:list, :tuple}],
description: description: "Restrict access of app metrics endpoint to the specified IP addresses."
"[Pleroma extension] If non-empty, restricts access to app metrics endpoint to specified IP addresses."
}, },
%{ %{
key: :auth, key: :auth,

View file

@ -1,4 +1,3 @@
firefox, /emoji/Firefox.gif, Gif,Fun firefox, /emoji/Firefox.gif, Gif,Fun
blank, /emoji/blank.png, Fun blank, /emoji/blank.png, Fun
dinosaur, /emoji/dino walking.gif, Gif dinosaur, /emoji/dino walking.gif, Gif
external_emoji, https://example.com/emoji.png

View file

@ -141,3 +141,21 @@ but should only be run if necessary. **It is safe to cancel this.**
```sh ```sh
mix pleroma.database ensure_expiration mix pleroma.database ensure_expiration
``` ```
## Change Text Search Configuration
Change `default_text_search_config` for database and (if necessary) text_search_config used in index, then rebuild index (it may take time).
=== "OTP"
```sh
./bin/pleroma_ctl database set_text_search_config english
```
=== "From Source"
```sh
mix pleroma.database set_text_search_config english
```
See [PostgreSQL documentation](https://www.postgresql.org/docs/current/textsearch-configuration.html) and `docs/configuration/howto_search_cjk.md` for more detail.

View file

@ -133,22 +133,20 @@
mix pleroma.user sign_out <nickname> mix pleroma.user sign_out <nickname>
``` ```
## Activate a user
## Deactivate or activate a user
=== "OTP" === "OTP"
```sh ```sh
./bin/pleroma_ctl user toggle_activated <nickname> ./bin/pleroma_ctl user activate NICKNAME
``` ```
=== "From Source" === "From Source"
```sh ```sh
mix pleroma.user toggle_activated <nickname> mix pleroma.user activate NICKNAME
``` ```
## Deactivate a user and unsubscribes local users from the user ## Deactivate a user and unsubscribes local users from the user
=== "OTP" === "OTP"

View file

@ -0,0 +1 @@
See `Authentication` section of [the configuration cheatsheet](../configuration/cheatsheet.md#authentication).

View file

@ -321,9 +321,10 @@ This section describe PWA manifest instance-specific values. Currently this opti
#### Pleroma.Web.MediaProxy.Invalidation.Script #### Pleroma.Web.MediaProxy.Invalidation.Script
This strategy allow perform external shell script to purge cache. This strategy allow perform external shell script to purge cache.
Urls of attachments pass to script as arguments. Urls of attachments are passed to the script as arguments.
* `script_path`: path to external script. * `script_path`: Path to the external script.
* `url_format`: Set to `:htcacheclean` if using Apache's htcacheclean utility.
Example: Example:
@ -892,6 +893,22 @@ Pleroma account will be created with the same name as the LDAP user name.
Note, if your LDAP server is an Active Directory server the correct value is commonly `uid: "cn"`, but if you use an Note, if your LDAP server is an Active Directory server the correct value is commonly `uid: "cn"`, but if you use an
OpenLDAP server the value may be `uid: "uid"`. OpenLDAP server the value may be `uid: "uid"`.
### :oauth2 (Pleroma as OAuth 2.0 provider settings)
OAuth 2.0 provider settings:
* `token_expires_in` - The lifetime in seconds of the access token.
* `issue_new_refresh_token` - Keeps old refresh token or generate new refresh token when to obtain an access token.
* `clean_expired_tokens` - Enable a background job to clean expired oauth tokens. Defaults to `false`.
OAuth 2.0 provider and related endpoints:
* `POST /api/v1/apps` creates client app basing on provided params.
* `GET/POST /oauth/authorize` renders/submits authorization form.
* `POST /oauth/token` creates/renews OAuth token.
* `POST /oauth/revoke` revokes provided OAuth token.
* `GET /api/v1/accounts/verify_credentials` (with proper `Authorization` header or `access_token` URI param) returns user info on requester (with `acct` field containing local nickname and `fqn` field containing fully-qualified nickname which could generally be used as email stub for OAuth software that demands email field in identity endpoint response, like Peertube).
### OAuth consumer mode ### OAuth consumer mode
OAuth consumer mode allows sign in / sign up via external OAuth providers (e.g. Twitter, Facebook, Google, Microsoft, etc.). OAuth consumer mode allows sign in / sign up via external OAuth providers (e.g. Twitter, Facebook, Google, Microsoft, etc.).
@ -964,14 +981,6 @@ config :ueberauth, Ueberauth,
] ]
``` ```
### OAuth 2.0 provider - :oauth2
Configure OAuth 2 provider capabilities:
* `token_expires_in` - The lifetime in seconds of the access token.
* `issue_new_refresh_token` - Keeps old refresh token or generate new refresh token when to obtain an access token.
* `clean_expired_tokens` - Enable a background job to clean expired oauth tokens. Defaults to `false`.
## Link parsing ## Link parsing
### :uri_schemes ### :uri_schemes

View file

@ -0,0 +1,42 @@
# How to enable text search for Chinese, Japanese and Korean
Pleroma's full text search feature is powered by PostgreSQL's native [text search](https://www.postgresql.org/docs/current/textsearch.html), it works well out of box for most of languages, but needs extra configurations for some asian languages like Chinese, Japanese and Korean (CJK).
## Setup and test the new search config
In most cases, you would need an extension installed to support parsing CJK text. Here are a few extension you may choose from, or you are more than welcome to share additional ones you found working for you with the rest of Pleroma community.
* [a generic n-gram parser](https://github.com/huangjimmy/pg_cjk_parser) supports Simplifed/Traditional Chinese, Japanese, and Korean
* [a Korean parser](https://github.com/i0seph/textsearch_ko) based on mecab
* [a Japanese parser](https://www.amris.co.jp/tsja/index.html) based on mecab
* [zhparser](https://github.com/amutu/zhparser/) is a PostgreSQL extension base on the Simple Chinese Word Segmentation(SCWS)
* [another Chinese parser](https://github.com/jaiminpan/pg_jieba) based on Jieba Chinese Word Segmentation
Once you have the new search config , make sure you test it with the `pleroma` user in PostgreSQL (change `YOUR.CONFIG` to your real configuration name)
```
SELECT ts_debug('YOUR.CONFIG', '安装和配置Nginx, ElixirとErlangをインストールします');
```
Check output of the query, and see if it matches your expectation.
## Update text search config and index in database
=== "OTP"
```sh
./bin/pleroma_ctl database set_text_search_config YOUR.CONFIG
```
=== "From Source"
```sh
mix pleroma.database set_text_search_config YOUR.CONFIG
```
Note: index update may take a while.
## Restart database connection
Since some changes above will only apply with a new database connection, you will have to restart either Pleroma or PostgreSQL process, or use `pg_terminate_backend` SQL command without restarting either.
Now the search results of statuses should be much more friendly for your language of choice, the results for searching users and tags were not changed, as the default parsing/matching should work for most cases.

View file

@ -2,13 +2,6 @@
Authentication is required and the user must be an admin. Authentication is required and the user must be an admin.
Configuration options:
* `[:auth, :enforce_oauth_admin_scope_usage]` — OAuth admin scope requirement toggle.
If `true`, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes).
If `false` and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions.
Note that client app needs to explicitly support admin scopes and request them when obtaining auth token.
## `GET /api/pleroma/admin/users` ## `GET /api/pleroma/admin/users`
### List users ### List users
@ -287,7 +280,18 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- *optional* `with_reblogs`: `true`/`false` allows to see reblogs (default is false) - *optional* `with_reblogs`: `true`/`false` allows to see reblogs (default is false)
- Response: - Response:
- On failure: `Not found` - On failure: `Not found`
- On success: JSON array of user's latest statuses - On success: JSON, where:
- `total`: total count of the statuses for the user
- `activities`: list of the statuses for the user
```json
{
"total" : 1,
"activities": [
// activities list
]
}
```
## `GET /api/pleroma/admin/instances/:instance/statuses` ## `GET /api/pleroma/admin/instances/:instance/statuses`
@ -300,7 +304,18 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- *optional* `with_reblogs`: `true`/`false` allows to see reblogs (default is false) - *optional* `with_reblogs`: `true`/`false` allows to see reblogs (default is false)
- Response: - Response:
- On failure: `Not found` - On failure: `Not found`
- On success: JSON array of instance's latest statuses - On success: JSON, where:
- `total`: total count of the statuses for the instance
- `activities`: list of the statuses for the instance
```json
{
"total" : 1,
"activities": [
// activities list
]
}
```
## `GET /api/pleroma/admin/statuses` ## `GET /api/pleroma/admin/statuses`

View file

@ -16,6 +16,12 @@ Adding the parameter `reply_visibility` to the public and home timelines queries
Adding the parameter `instance=lain.com` to the public timeline will show only statuses originating from `lain.com` (or any remote instance). Adding the parameter `instance=lain.com` to the public timeline will show only statuses originating from `lain.com` (or any remote instance).
Home, public, hashtag & list timelines accept these parameters:
- `only_media`: show only statuses with media attached
- `local`: show only local statuses
- `remote`: show only remote statuses
## Statuses ## Statuses
- `visibility`: has additional possible values `list` and `local` (for local-only statuses) - `visibility`: has additional possible values `list` and `local` (for local-only statuses)
@ -54,6 +60,23 @@ The `id` parameter can also be the `nickname` of the user. This only works in th
- `/api/v1/accounts/:id` - `/api/v1/accounts/:id`
- `/api/v1/accounts/:id/statuses` - `/api/v1/accounts/:id/statuses`
`/api/v1/accounts/:id/statuses` endpoint accepts these parameters:
- `pinned`: include only pinned statuses
- `tagged`: with tag
- `only_media`: include only statuses with media attached
- `with_muted`: include statuses/reactions from muted accounts
- `exclude_reblogs`: exclude reblogs
- `exclude_replies`: exclude replies
- `exclude_visibilities`: exclude visibilities
Endpoints which accept `with_relationships` parameter:
- `/api/v1/accounts/:id`
- `/api/v1/accounts/:id/followers`
- `/api/v1/accounts/:id/following`
- `/api/v1/mutes`
Has these additional fields under the `pleroma` object: Has these additional fields under the `pleroma` object:
- `ap_id`: nullable URL string, ActivityPub id of the user - `ap_id`: nullable URL string, ActivityPub id of the user

View file

@ -0,0 +1,36 @@
#!/bin/sh
# A simple shell script to delete a media from Apache's mod_disk_cache.
# You will likely need to setup a sudo rule like the following:
#
# Cmnd_Alias HTCACHECLEAN = /usr/local/sbin/htcacheclean
# pleroma ALL=HTCACHECLEAN, NOPASSWD: HTCACHECLEAN
#
# Please also ensure you have enabled:
#
# config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script, url_format: :htcacheclean
#
# which will correctly format the URLs passed to this script for the htcacheclean utility.
#
SCRIPTNAME=${0##*/}
# mod_disk_cache directory
CACHE_DIRECTORY="/tmp/pleroma-media-cache"
## Removes an item via the htcacheclean utility
## $1 - the filename, can be a pattern .
## $2 - the cache directory.
purge_item() {
sudo htcacheclean -v -p "${2}" "${1}"
} # purge_item
purge() {
for url in $@
do
echo "$SCRIPTNAME delete \`$url\` from cache ($CACHE_DIRECTORY)"
purge_item "$url" $CACHE_DIRECTORY
done
}
purge $@

View file

@ -1,73 +1,84 @@
# default Apache site config for Pleroma # Sample Apache config for Pleroma
#
# needed modules: define headers proxy proxy_http proxy_wstunnel rewrite ssl
# optional modules: cache cache_disk
# #
# Simple installation instructions: # Simple installation instructions:
# 1. Install your TLS certificate, possibly using Let's Encrypt. # 1. Install your TLS certificate. We recommend using Let's Encrypt via Certbot
# 2. Replace 'example.tld' with your instance's domain wherever it appears. # 2. Replace 'example.tld' with your instance's domain.
# 3. This assumes a Debian style Apache config. Copy this file to # 3. This assumes a Debian-style Apache config. Copy this file to
# /etc/apache2/sites-available/ and then add a symlink to it in # /etc/apache2/sites-available/ and then activate the site by running
# /etc/apache2/sites-enabled/ by running 'a2ensite pleroma-apache.conf', then restart Apache. # 'a2ensite pleroma-apache.conf', then restart Apache.
# #
# Optional: enable disk-based caching for the media proxy # Optional: enable disk-based caching for the media proxy
# For details, see https://git.pleroma.social/pleroma/pleroma/wikis/How%20to%20activate%20mediaproxy # For details, see https://git.pleroma.social/pleroma/pleroma/wikis/How%20to%20activate%20mediaproxy
# #
# 1. Create the directory listed below as the CacheRoot, and make sure # 1. Create a directory as shown below for the CacheRoot and make sure
# the Apache user can write to it. # the Apache user can write to it.
# 2. Configure Apache's htcacheclean to clean the directory periodically. # 2. Configure Apache's htcacheclean to clean the directory periodically.
# 3. Run 'a2enmod cache cache_disk' and restart Apache. # Your OS may provide a service you can enable to do this automatically.
Define servername example.tld Define servername example.tld
<IfModule !proxy_module>
LoadModule proxy_module libexec/apache24/mod_proxy.so
</IfModule>
<IfModule !proxy_http_module>
LoadModule proxy_http_module libexec/apache24/mod_proxy_http.so
</IfModule>
<IfModule !proxy_wstunnel_module>
LoadModule proxy_wstunnel_module libexec/apache24/mod_proxy_wstunnel.so
</IfModule>
<IfModule !rewrite_module>
LoadModule rewrite_module libexec/apache24/mod_rewrite.so
</IfModule>
<IfModule !ssl_module>
LoadModule ssl_module libexec/apache24/mod_ssl.so
</IfModule>
<IfModule !cache_module>
LoadModule cache_module libexec/apache24/mod_cache.so
</IfModule>
<IfModule !cache_disk_module>
LoadModule cache_disk_module libexec/apache24/mod_cache_disk.so
</IfModule>
ServerName ${servername} ServerName ${servername}
ServerTokens Prod ServerTokens Prod
ErrorLog ${APACHE_LOG_DIR}/error.log # If you want Pleroma-specific logs
CustomLog ${APACHE_LOG_DIR}/access.log combined #ErrorLog /var/log/httpd-pleroma-error.log
#CustomLog /var/log/httpd-pleroma-access.log combined
<VirtualHost *:80> <VirtualHost *:80>
Redirect permanent / https://${servername} RewriteEngine on
RewriteCond %{SERVER_NAME} =${servername}
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost> </VirtualHost>
<VirtualHost *:443> <VirtualHost *:443>
SSLEngine on SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/${servername}/fullchain.pem SSLCertificateFile /etc/letsencrypt/live/${servername}/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/${servername}/privkey.pem SSLCertificateKeyFile /etc/letsencrypt/live/${servername}/privkey.pem
# Make sure you have the certbot-apache module installed
Include /etc/letsencrypt/options-ssl-apache.conf
# Mozilla modern configuration, tweak to your needs # Uncomment the following to enable MediaProxy caching on disk
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 #CacheRoot /tmp/pleroma-media-cache/
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
# uncomment the following to enable mediaproxy caching on disk
# <IfModule mod_cache_disk.c>
# CacheRoot /var/cache/apache2/mod_cache_disk
#CacheDirLevels 1 #CacheDirLevels 1
#CacheDirLength 2 #CacheDirLength 2
#CacheEnable disk /proxy #CacheEnable disk /proxy
#CacheLock on #CacheLock on
# </IfModule> #CacheHeader on
#CacheDetailHeader on
## 16MB max filesize for caching, configure as desired
#CacheMaxFileSize 16000000
#CacheDefaultExpire 86400
RewriteEngine On RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC] RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://localhost:4000/$1 [P,L] RewriteRule /(.*) ws://127.0.0.1:4000/$1 [P,L]
#ProxyRequests must be off or you open your server to abuse as an open proxy
ProxyRequests off ProxyRequests off
# this is explicitly IPv4 since Pleroma.Web.Endpoint binds on IPv4 only
# and `localhost.` resolves to [::0] on some systems: see issue #930
ProxyPass / http://127.0.0.1:4000/ ProxyPass / http://127.0.0.1:4000/
ProxyPassReverse / http://127.0.0.1:4000/ ProxyPassReverse / http://127.0.0.1:4000/
RequestHeader set Host ${servername}
ProxyPreserveHost On ProxyPreserveHost On
</VirtualHost> </VirtualHost>
# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)

View file

@ -59,6 +59,13 @@ sub vcl_backend_response {
set beresp.http.CR = beresp.http.content-range; set beresp.http.CR = beresp.http.content-range;
} }
# Bypass cache for large files
# 50000000 ~ 50MB
if (std.integer(beresp.http.content-length, 0) > 50000000) {
set beresp.uncacheable = true;
return(deliver);
}
# Don't cache objects that require authentication # Don't cache objects that require authentication
if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") { if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") {
set beresp.uncacheable = true; set beresp.uncacheable = true;

View file

@ -167,4 +167,51 @@ defmodule Mix.Tasks.Pleroma.Database do
end) end)
|> Stream.run() |> Stream.run()
end end
def run(["set_text_search_config", tsconfig]) do
start_pleroma()
%{rows: [[tsc]]} = Ecto.Adapters.SQL.query!(Pleroma.Repo, "SHOW default_text_search_config;")
shell_info("Current default_text_search_config: #{tsc}")
%{rows: [[db]]} = Ecto.Adapters.SQL.query!(Pleroma.Repo, "SELECT current_database();")
shell_info("Update default_text_search_config: #{tsconfig}")
%{messages: msg} =
Ecto.Adapters.SQL.query!(
Pleroma.Repo,
"ALTER DATABASE #{db} SET default_text_search_config = '#{tsconfig}';"
)
# non-exist config will not raise excpetion but only give >0 messages
if length(msg) > 0 do
shell_info("Error: #{inspect(msg, pretty: true)}")
else
rum_enabled = Pleroma.Config.get([:database, :rum_enabled])
shell_info("Recreate index, RUM: #{rum_enabled}")
# Note SQL below needs to be kept up-to-date with latest GIN or RUM index definition in future
if rum_enabled do
Ecto.Adapters.SQL.query!(
Pleroma.Repo,
"CREATE OR REPLACE FUNCTION objects_fts_update() RETURNS trigger AS $$ BEGIN
new.fts_content := to_tsvector(new.data->>'content');
RETURN new;
END
$$ LANGUAGE plpgsql"
)
shell_info("Refresh RUM index")
Ecto.Adapters.SQL.query!(Pleroma.Repo, "UPDATE objects SET updated_at = NOW();")
else
Ecto.Adapters.SQL.query!(Pleroma.Repo, "DROP INDEX IF EXISTS objects_fts;")
Ecto.Adapters.SQL.query!(
Pleroma.Repo,
"CREATE INDEX objects_fts ON objects USING gin(to_tsvector('#{tsconfig}', data->>'content')); "
)
end
shell_info('Done.')
end
end
end end

View file

@ -33,12 +33,12 @@ defmodule Mix.Tasks.Pleroma.Email do
Pleroma.User.Query.build(%{ Pleroma.User.Query.build(%{
local: true, local: true,
deactivated: false, is_active: true,
is_confirmed: false, is_confirmed: false,
invisible: false invisible: false
}) })
|> Pleroma.Repo.chunk_stream(500) |> Pleroma.Repo.chunk_stream(500)
|> Stream.each(&Pleroma.User.try_send_confirmation_email(&1)) |> Stream.each(&Pleroma.User.maybe_send_confirmation_email(&1))
|> Stream.run() |> Stream.run()
end end
end end

View file

@ -242,6 +242,13 @@ defmodule Mix.Tasks.Pleroma.Instance do
rum_enabled: rum_enabled rum_enabled: rum_enabled
) )
config_dir = Path.dirname(config_path)
psql_dir = Path.dirname(psql_path)
[config_dir, psql_dir, static_dir, uploads_dir]
|> Enum.reject(&File.exists?/1)
|> Enum.map(&File.mkdir_p!/1)
shell_info("Writing config to #{config_path}.") shell_info("Writing config to #{config_path}.")
File.write(config_path, result_config) File.write(config_path, result_config)
@ -275,10 +282,6 @@ defmodule Mix.Tasks.Pleroma.Instance do
indexable: indexable indexable: indexable
) )
unless File.exists?(static_dir) do
File.mkdir_p!(static_dir)
end
robots_txt_path = Path.join(static_dir, "robots.txt") robots_txt_path = Path.join(static_dir, "robots.txt")
if File.exists?(robots_txt_path) do if File.exists?(robots_txt_path) do

View file

@ -0,0 +1,8 @@
defmodule Mix.Tasks.Pleroma.OpenapiSpec do
def run([path]) do
# Load Pleroma application to get version info
Application.load(:pleroma)
spec = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
File.write(path, spec)
end
end

View file

@ -107,21 +107,6 @@ defmodule Mix.Tasks.Pleroma.User do
end end
end end
def run(["toggle_activated", nickname]) do
start_pleroma()
with %User{} = user <- User.get_cached_by_nickname(nickname) do
{:ok, user} = User.deactivate(user, !user.deactivated)
shell_info(
"Activation status of #{nickname}: #{if(user.deactivated, do: "de", else: "")}activated"
)
else
_ ->
shell_error("No user #{nickname}")
end
end
def run(["reset_password", nickname]) do def run(["reset_password", nickname]) do
start_pleroma() start_pleroma()
@ -156,20 +141,41 @@ defmodule Mix.Tasks.Pleroma.User do
end end
end end
def run(["activate", nickname]) do
start_pleroma()
with %User{} = user <- User.get_cached_by_nickname(nickname),
false <- user.is_active do
User.set_activation(user, true)
:timer.sleep(500)
shell_info("Successfully activated #{nickname}")
else
true ->
shell_info("User #{nickname} already activated")
_ ->
shell_error("No user #{nickname}")
end
end
def run(["deactivate", nickname]) do def run(["deactivate", nickname]) do
start_pleroma() start_pleroma()
with %User{} = user <- User.get_cached_by_nickname(nickname) do with %User{} = user <- User.get_cached_by_nickname(nickname),
shell_info("Deactivating #{user.nickname}") true <- user.is_active do
User.deactivate(user) User.set_activation(user, false)
:timer.sleep(500) :timer.sleep(500)
user = User.get_cached_by_id(user.id) user = User.get_cached_by_id(user.id)
if Enum.empty?(Enum.filter(User.get_friends(user), & &1.local)) do if Enum.empty?(Enum.filter(User.get_friends(user), & &1.local)) do
shell_info("Successfully unsubscribed all local followers from #{user.nickname}") shell_info("Successfully deactivated #{nickname} and unsubscribed all local followers")
end end
else else
false ->
shell_info("User #{nickname} already deactivated")
_ -> _ ->
shell_error("No user #{nickname}") shell_error("No user #{nickname}")
end end
@ -398,7 +404,7 @@ defmodule Mix.Tasks.Pleroma.User do
Pleroma.User.Query.build(%{ Pleroma.User.Query.build(%{
local: true, local: true,
deactivated: false, is_active: true,
is_moderator: false, is_moderator: false,
is_admin: false, is_admin: false,
invisible: false invisible: false
@ -416,7 +422,7 @@ defmodule Mix.Tasks.Pleroma.User do
Pleroma.User.Query.build(%{ Pleroma.User.Query.build(%{
local: true, local: true,
deactivated: false, is_active: true,
is_moderator: false, is_moderator: false,
is_admin: false, is_admin: false,
invisible: false invisible: false
@ -453,7 +459,7 @@ defmodule Mix.Tasks.Pleroma.User do
shell_info( shell_info(
"#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{ "#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{
user.is_locked user.is_locked
}, deactivated: #{user.deactivated}" }, is_active: #{user.is_active}"
) )
end) end)
end) end)

View file

@ -64,7 +64,7 @@ defmodule Pleroma.Activity.Search do
from([a, o] in q, from([a, o] in q,
where: where:
fragment( fragment(
"to_tsvector('english', ?->>'content') @@ plainto_tsquery('english', ?)", "to_tsvector(?->>'content') @@ plainto_tsquery(?)",
o.data, o.data,
^search_query ^search_query
) )
@ -75,7 +75,7 @@ defmodule Pleroma.Activity.Search do
from([a, o] in q, from([a, o] in q,
where: where:
fragment( fragment(
"to_tsvector('english', ?->>'content') @@ websearch_to_tsquery('english', ?)", "to_tsvector(?->>'content') @@ websearch_to_tsquery(?)",
o.data, o.data,
^search_query ^search_query
) )
@ -86,7 +86,7 @@ defmodule Pleroma.Activity.Search do
from([a, o] in q, from([a, o] in q,
where: where:
fragment( fragment(
"? @@ plainto_tsquery('english', ?)", "? @@ plainto_tsquery(?)",
o.fts_content, o.fts_content,
^search_query ^search_query
), ),
@ -98,7 +98,7 @@ defmodule Pleroma.Activity.Search do
from([a, o] in q, from([a, o] in q,
where: where:
fragment( fragment(
"? @@ websearch_to_tsquery('english', ?)", "? @@ websearch_to_tsquery(?)",
o.fts_content, o.fts_content,
^search_query ^search_query
), ),

View file

@ -14,7 +14,7 @@ defmodule Pleroma.Application do
@name Mix.Project.config()[:name] @name Mix.Project.config()[:name]
@version Mix.Project.config()[:version] @version Mix.Project.config()[:version]
@repository Mix.Project.config()[:source_url] @repository Mix.Project.config()[:source_url]
@env Mix.env() @mix_env Mix.env()
def name, do: @name def name, do: @name
def version, do: @version def version, do: @version
@ -92,15 +92,15 @@ defmodule Pleroma.Application do
Pleroma.Web.Plugs.RateLimiter.Supervisor Pleroma.Web.Plugs.RateLimiter.Supervisor
] ++ ] ++
cachex_children() ++ cachex_children() ++
http_children(adapter, @env) ++ http_children(adapter, @mix_env) ++
[ [
Pleroma.Stats, Pleroma.Stats,
Pleroma.JobQueueMonitor, Pleroma.JobQueueMonitor,
{Majic.Pool, [name: Pleroma.MajicPool, pool_size: Config.get([:majic_pool, :size], 2)]}, {Majic.Pool, [name: Pleroma.MajicPool, pool_size: Config.get([:majic_pool, :size], 2)]},
{Oban, Config.get(Oban)} {Oban, Config.get(Oban)}
] ++ ] ++
task_children(@env) ++ task_children(@mix_env) ++
dont_run_in_test(@env) ++ dont_run_in_test(@mix_env) ++
chat_child(chat_enabled?()) ++ chat_child(chat_enabled?()) ++
[ [
Pleroma.Web.Endpoint, Pleroma.Web.Endpoint,
@ -145,7 +145,7 @@ defmodule Pleroma.Application do
raise "Invalid custom modules" raise "Invalid custom modules"
{:ok, modules, _warnings} -> {:ok, modules, _warnings} ->
if @env != :test do if @mix_env != :test do
Enum.each(modules, fn mod -> Enum.each(modules, fn mod ->
Logger.info("Custom module loaded: #{inspect(mod)}") Logger.info("Custom module loaded: #{inspect(mod)}")
end) end)

View file

@ -99,16 +99,4 @@ defmodule Pleroma.Config do
def oauth_consumer_strategies, do: get([:auth, :oauth_consumer_strategies], []) def oauth_consumer_strategies, do: get([:auth, :oauth_consumer_strategies], [])
def oauth_consumer_enabled?, do: oauth_consumer_strategies() != [] def oauth_consumer_enabled?, do: oauth_consumer_strategies() != []
def enforce_oauth_admin_scope_usage?, do: !!get([:auth, :enforce_oauth_admin_scope_usage])
def oauth_admin_scopes(scopes) when is_list(scopes) do
Enum.flat_map(
scopes,
fn scope ->
["admin:#{scope}"] ++
if enforce_oauth_admin_scope_usage?(), do: [], else: [scope]
end
)
end
end end

View file

@ -61,9 +61,8 @@ defmodule Pleroma.Conversation do
"Create" <- activity.data["type"], "Create" <- activity.data["type"],
%Object{} = object <- Object.normalize(activity, fetch: false), %Object{} = object <- Object.normalize(activity, fetch: false),
true <- object.data["type"] in ["Note", "Question"], true <- object.data["type"] in ["Note", "Question"],
ap_id when is_binary(ap_id) and byte_size(ap_id) > 0 <- object.data["context"] do ap_id when is_binary(ap_id) and byte_size(ap_id) > 0 <- object.data["context"],
{:ok, conversation} = create_for_ap_id(ap_id) {:ok, conversation} <- create_for_ap_id(ap_id) do
users = User.get_users_from_set(activity.recipients, local_only: false) users = User.get_users_from_set(activity.recipients, local_only: false)
participations = participations =

View file

@ -220,4 +220,8 @@ defmodule Pleroma.Conversation.Participation do
select: %{count: count(p.id)} select: %{count: count(p.id)}
) )
end end
def delete(%__MODULE__{} = participation) do
Repo.delete(participation)
end
end end

View file

@ -81,9 +81,9 @@ defmodule Pleroma.Emails.UserEmail do
) )
html_body = """ html_body = """
<h3>Welcome to #{instance_name()}!</h3> <h3>Thank you for registering on #{instance_name()}</h3>
<p>Email confirmation is required to activate the account.</p> <p>Email confirmation is required to activate the account.</p>
<p>Click the following link to proceed: <a href="#{confirmation_url}">activate your account</a>.</p> <p>Please click the following link to <a href="#{confirmation_url}">activate your account</a>.</p>
""" """
new() new()
@ -106,6 +106,20 @@ defmodule Pleroma.Emails.UserEmail do
|> html_body(html_body) |> html_body(html_body)
end end
def successful_registration_email(user) do
html_body = """
<h3>Hello @#{user.nickname},</h3>
<p>Your account at #{instance_name()} has been registered successfully.</p>
<p>No further action is required to activate your account.</p>
"""
new()
|> to(recipient(user))
|> from(sender())
|> subject("Account registered on #{instance_name()}")
|> html_body(html_body)
end
@doc """ @doc """
Email used in digest email notifications Email used in digest email notifications
Includes Mentions and New Followers data Includes Mentions and New Followers data

View file

@ -15,6 +15,8 @@ defmodule Pleroma.Emoji.Loader do
require Logger require Logger
@mix_env Mix.env()
@type pattern :: Regex.t() | module() | String.t() @type pattern :: Regex.t() | module() | String.t()
@type patterns :: pattern() | [pattern()] @type patterns :: pattern() | [pattern()]
@type group_patterns :: keyword(patterns()) @type group_patterns :: keyword(patterns())
@ -77,10 +79,19 @@ defmodule Pleroma.Emoji.Loader do
# it should run even if there are no emoji packs # it should run even if there are no emoji packs
shortcode_globs = Config.get([:emoji, :shortcode_globs], []) shortcode_globs = Config.get([:emoji, :shortcode_globs], [])
# for testing emoji.txt entries we do not want exposed in normal operation
test_emoji =
if @mix_env == :test do
load_from_file("test/config/emoji.txt", emoji_groups)
else
[]
end
emojis_txt = emojis_txt =
(load_from_file("config/emoji.txt", emoji_groups) ++ (load_from_file("config/emoji.txt", emoji_groups) ++
load_from_file("config/custom_emoji.txt", emoji_groups) ++ load_from_file("config/custom_emoji.txt", emoji_groups) ++
load_from_globs(shortcode_globs, emoji_groups)) load_from_globs(shortcode_globs, emoji_groups) ++
test_emoji)
|> Enum.reject(fn value -> value == nil end) |> Enum.reject(fn value -> value == nil end)
Enum.map(emojis ++ emojis_txt, &prepare_emoji/1) Enum.map(emojis ++ emojis_txt, &prepare_emoji/1)

View file

@ -11,6 +11,9 @@ defmodule Pleroma.Filter do
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
@type t() :: %__MODULE__{}
@type format() :: :postgres | :re
schema "filters" do schema "filters" do
belongs_to(:user, User, type: FlakeId.Ecto.CompatType) belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
field(:filter_id, :integer) field(:filter_id, :integer)
@ -18,15 +21,16 @@ defmodule Pleroma.Filter do
field(:whole_word, :boolean, default: true) field(:whole_word, :boolean, default: true)
field(:phrase, :string) field(:phrase, :string)
field(:context, {:array, :string}) field(:context, {:array, :string})
field(:expires_at, :utc_datetime) field(:expires_at, :naive_datetime)
timestamps() timestamps()
end end
@spec get(integer() | String.t(), User.t()) :: t() | nil
def get(id, %{id: user_id} = _user) do def get(id, %{id: user_id} = _user) do
query = query =
from( from(
f in Pleroma.Filter, f in __MODULE__,
where: f.filter_id == ^id, where: f.filter_id == ^id,
where: f.user_id == ^user_id where: f.user_id == ^user_id
) )
@ -34,14 +38,17 @@ defmodule Pleroma.Filter do
Repo.one(query) Repo.one(query)
end end
@spec get_active(Ecto.Query.t() | module()) :: Ecto.Query.t()
def get_active(query) do def get_active(query) do
from(f in query, where: is_nil(f.expires_at) or f.expires_at > ^NaiveDateTime.utc_now()) from(f in query, where: is_nil(f.expires_at) or f.expires_at > ^NaiveDateTime.utc_now())
end end
@spec get_irreversible(Ecto.Query.t()) :: Ecto.Query.t()
def get_irreversible(query) do def get_irreversible(query) do
from(f in query, where: f.hide) from(f in query, where: f.hide)
end end
@spec get_filters(Ecto.Query.t() | module(), User.t()) :: [t()]
def get_filters(query \\ __MODULE__, %User{id: user_id}) do def get_filters(query \\ __MODULE__, %User{id: user_id}) do
query = query =
from( from(
@ -53,7 +60,32 @@ defmodule Pleroma.Filter do
Repo.all(query) Repo.all(query)
end end
def create(%Pleroma.Filter{user_id: user_id, filter_id: nil} = filter) do @spec create(map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
def create(attrs \\ %{}) do
Repo.transaction(fn -> create_with_expiration(attrs) end)
end
defp create_with_expiration(attrs) do
with {:ok, filter} <- do_create(attrs),
{:ok, _} <- maybe_add_expiration_job(filter) do
filter
else
{:error, error} -> Repo.rollback(error)
end
end
defp do_create(attrs) do
%__MODULE__{}
|> cast(attrs, [:phrase, :context, :hide, :expires_at, :whole_word, :user_id, :filter_id])
|> maybe_add_filter_id()
|> validate_required([:phrase, :context, :user_id, :filter_id])
|> maybe_add_expires_at(attrs)
|> Repo.insert()
end
defp maybe_add_filter_id(%{changes: %{filter_id: _}} = changeset), do: changeset
defp maybe_add_filter_id(%{changes: %{user_id: user_id}} = changeset) do
# If filter_id wasn't given, use the max filter_id for this user plus 1. # If filter_id wasn't given, use the max filter_id for this user plus 1.
# XXX This could result in a race condition if a user tries to add two # XXX This could result in a race condition if a user tries to add two
# different filters for their account from two different clients at the # different filters for their account from two different clients at the
@ -61,7 +93,7 @@ defmodule Pleroma.Filter do
max_id_query = max_id_query =
from( from(
f in Pleroma.Filter, f in __MODULE__,
where: f.user_id == ^user_id, where: f.user_id == ^user_id,
select: max(f.filter_id) select: max(f.filter_id)
) )
@ -76,34 +108,92 @@ defmodule Pleroma.Filter do
max_id + 1 max_id + 1
end end
change(changeset, filter_id: filter_id)
end
# don't override expires_at, if passed expires_at and expires_in
defp maybe_add_expires_at(%{changes: %{expires_at: %NaiveDateTime{} = _}} = changeset, _) do
changeset
end
defp maybe_add_expires_at(changeset, %{expires_in: expires_in})
when is_integer(expires_in) and expires_in > 0 do
expires_at =
NaiveDateTime.utc_now()
|> NaiveDateTime.add(expires_in)
|> NaiveDateTime.truncate(:second)
change(changeset, expires_at: expires_at)
end
defp maybe_add_expires_at(changeset, %{expires_in: nil}) do
change(changeset, expires_at: nil)
end
defp maybe_add_expires_at(changeset, _), do: changeset
defp maybe_add_expiration_job(%{expires_at: %NaiveDateTime{} = expires_at} = filter) do
Pleroma.Workers.PurgeExpiredFilter.enqueue(%{
filter_id: filter.id,
expires_at: DateTime.from_naive!(expires_at, "Etc/UTC")
})
end
defp maybe_add_expiration_job(_), do: {:ok, nil}
@spec delete(t()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
def delete(%__MODULE__{} = filter) do
Repo.transaction(fn -> delete_with_expiration(filter) end)
end
defp delete_with_expiration(filter) do
with {:ok, _} <- maybe_delete_old_expiration_job(filter, nil),
{:ok, filter} <- Repo.delete(filter) do
filter filter
|> Map.put(:filter_id, filter_id) else
|> Repo.insert() {:error, error} -> Repo.rollback(error)
end
end end
def create(%Pleroma.Filter{} = filter) do @spec update(t(), map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
Repo.insert(filter) def update(%__MODULE__{} = filter, params) do
Repo.transaction(fn -> update_with_expiration(filter, params) end)
end end
def delete(%Pleroma.Filter{id: filter_key} = filter) when is_number(filter_key) do defp update_with_expiration(filter, params) do
Repo.delete(filter) with {:ok, updated} <- do_update(filter, params),
{:ok, _} <- maybe_delete_old_expiration_job(filter, updated),
{:ok, _} <-
maybe_add_expiration_job(updated) do
updated
else
{:error, error} -> Repo.rollback(error)
end
end end
def delete(%Pleroma.Filter{id: filter_key} = filter) when is_nil(filter_key) do defp do_update(filter, params) do
%Pleroma.Filter{id: id} = get(filter.filter_id, %{id: filter.user_id})
filter
|> Map.put(:id, id)
|> Repo.delete()
end
def update(%Pleroma.Filter{} = filter, params) do
filter filter
|> cast(params, [:phrase, :context, :hide, :expires_at, :whole_word]) |> cast(params, [:phrase, :context, :hide, :expires_at, :whole_word])
|> validate_required([:phrase, :context]) |> validate_required([:phrase, :context])
|> maybe_add_expires_at(params)
|> Repo.update() |> Repo.update()
end end
defp maybe_delete_old_expiration_job(%{expires_at: nil}, _), do: {:ok, nil}
defp maybe_delete_old_expiration_job(%{expires_at: expires_at}, %{expires_at: expires_at}) do
{:ok, nil}
end
defp maybe_delete_old_expiration_job(%{id: id}, _) do
with %Oban.Job{} = job <- Pleroma.Workers.PurgeExpiredFilter.get_expiration(id) do
Repo.delete(job)
else
nil -> {:ok, nil}
end
end
@spec compose_regex(User.t() | [t()], format()) :: String.t() | Regex.t() | nil
def compose_regex(user_or_filters, format \\ :postgres) def compose_regex(user_or_filters, format \\ :postgres)
def compose_regex(%User{} = user, format) do def compose_regex(%User{} = user, format) do

View file

@ -152,7 +152,7 @@ defmodule Pleroma.FollowingRelationship do
|> join(:inner, [r], f in assoc(r, :follower)) |> join(:inner, [r], f in assoc(r, :follower))
|> where([r], r.state == ^:follow_pending) |> where([r], r.state == ^:follow_pending)
|> where([r], r.following_id == ^id) |> where([r], r.following_id == ^id)
|> where([r, f], f.deactivated != true) |> where([r, f], f.is_active == true)
|> select([r, f], f) |> select([r, f], f)
|> Repo.all() |> Repo.all()
end end

View file

@ -113,11 +113,15 @@ defmodule Pleroma.List do
end end
end end
def follow(%Pleroma.List{following: following} = list, %User{} = followed) do def follow(%Pleroma.List{id: id}, %User{} = followed) do
list = Repo.get(Pleroma.List, id)
%{following: following} = list
update_follows(list, %{following: Enum.uniq([followed.follower_address | following])}) update_follows(list, %{following: Enum.uniq([followed.follower_address | following])})
end end
def unfollow(%Pleroma.List{following: following} = list, %User{} = unfollowed) do def unfollow(%Pleroma.List{id: id}, %User{} = unfollowed) do
list = Repo.get(Pleroma.List, id)
%{following: following} = list
update_follows(list, %{following: List.delete(following, unfollowed.follower_address)}) update_follows(list, %{following: List.delete(following, unfollowed.follower_address)})
end end

View file

@ -112,13 +112,6 @@ defmodule Pleroma.Notification do
Notification Notification
|> where(user_id: ^user.id) |> where(user_id: ^user.id)
|> where(
[n, a],
fragment(
"? not in (SELECT ap_id FROM users WHERE deactivated = 'true')",
a.actor
)
)
|> join(:inner, [n], activity in assoc(n, :activity)) |> join(:inner, [n], activity in assoc(n, :activity))
|> join(:left, [n, a], object in Object, |> join(:left, [n, a], object in Object,
on: on:
@ -129,7 +122,9 @@ defmodule Pleroma.Notification do
a.data a.data
) )
) )
|> join(:inner, [_n, a], u in User, on: u.ap_id == a.actor, as: :user_actor)
|> preload([n, a, o], activity: {a, object: o}) |> preload([n, a, o], activity: {a, object: o})
|> where([user_actor: user_actor], user_actor.is_active)
|> exclude_notification_muted(user, exclude_notification_muted_opts) |> exclude_notification_muted(user, exclude_notification_muted_opts)
|> exclude_blocked(user, exclude_blocked_opts) |> exclude_blocked(user, exclude_blocked_opts)
|> exclude_filtered(user) |> exclude_filtered(user)
@ -156,9 +151,10 @@ defmodule Pleroma.Notification do
query query
|> where([n, a], a.actor not in ^notification_muted_ap_ids) |> where([n, a], a.actor not in ^notification_muted_ap_ids)
|> join(:left, [n, a], tm in ThreadMute, |> join(:left, [n, a], tm in ThreadMute,
on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data) on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data),
as: :thread_mute
) )
|> where([n, a, o, tm], is_nil(tm.user_id)) |> where([thread_mute: thread_mute], is_nil(thread_mute.user_id))
end end
defp exclude_filtered(query, user) do defp exclude_filtered(query, user) do
@ -507,8 +503,8 @@ defmodule Pleroma.Notification do
[object_id] [object_id]
end end
def get_potential_receiver_ap_ids(%{data: %{"type" => "Flag"}}) do def get_potential_receiver_ap_ids(%{data: %{"type" => "Flag", "actor" => actor}}) do
User.all_superusers() |> Enum.map(fn user -> user.ap_id end) (User.all_superusers() |> Enum.map(fn user -> user.ap_id end)) -- [actor]
end end
def get_potential_receiver_ap_ids(activity) do def get_potential_receiver_ap_ids(activity) do

View file

@ -75,7 +75,7 @@ defmodule Pleroma.Stats do
users_query = users_query =
from(u in User, from(u in User,
where: u.deactivated != true, where: u.is_active == true,
where: u.local == true, where: u.local == true,
where: not is_nil(u.nickname), where: not is_nil(u.nickname),
where: not u.invisible where: not u.invisible

View file

@ -5,6 +5,8 @@
defmodule Pleroma.Uploaders.Uploader do defmodule Pleroma.Uploaders.Uploader do
import Pleroma.Web.Gettext import Pleroma.Web.Gettext
@mix_env Mix.env()
@moduledoc """ @moduledoc """
Defines the contract to put and get an uploaded file to any backend. Defines the contract to put and get an uploaded file to any backend.
""" """
@ -74,7 +76,7 @@ defmodule Pleroma.Uploaders.Uploader do
end end
defp callback_timeout do defp callback_timeout do
case Mix.env() do case @mix_env do
:test -> 1_000 :test -> 1_000
_ -> 30_000 _ -> 30_000
end end

View file

@ -117,7 +117,7 @@ defmodule Pleroma.User do
field(:confirmation_token, :string, default: nil) field(:confirmation_token, :string, default: nil)
field(:default_scope, :string, default: "public") field(:default_scope, :string, default: "public")
field(:domain_blocks, {:array, :string}, default: []) field(:domain_blocks, {:array, :string}, default: [])
field(:deactivated, :boolean, default: false) field(:is_active, :boolean, default: true)
field(:no_rich_text, :boolean, default: false) field(:no_rich_text, :boolean, default: false)
field(:ap_enabled, :boolean, default: false) field(:ap_enabled, :boolean, default: false)
field(:is_moderator, :boolean, default: false) field(:is_moderator, :boolean, default: false)
@ -146,6 +146,7 @@ defmodule Pleroma.User do
field(:inbox, :string) field(:inbox, :string)
field(:shared_inbox, :string) field(:shared_inbox, :string)
field(:accepts_chat_messages, :boolean, default: nil) field(:accepts_chat_messages, :boolean, default: nil)
field(:last_active_at, :naive_datetime)
embeds_one( embeds_one(
:notification_settings, :notification_settings,
@ -217,7 +218,8 @@ defmodule Pleroma.User do
target_users_query = assoc(user, unquote(outgoing_relation_target)) target_users_query = assoc(user, unquote(outgoing_relation_target))
if restrict_deactivated? do if restrict_deactivated? do
restrict_deactivated(target_users_query) target_users_query
|> User.Query.build(%{deactivated: false})
else else
target_users_query target_users_query
end end
@ -286,7 +288,7 @@ defmodule Pleroma.User do
@doc "Returns status account" @doc "Returns status account"
@spec account_status(User.t()) :: account_status() @spec account_status(User.t()) :: account_status()
def account_status(%User{deactivated: true}), do: :deactivated def account_status(%User{is_active: false}), do: :deactivated
def account_status(%User{password_reset_pending: true}), do: :password_reset_pending def account_status(%User{password_reset_pending: true}), do: :password_reset_pending
def account_status(%User{local: true, is_approved: false}), do: :approval_pending def account_status(%User{local: true, is_approved: false}), do: :approval_pending
def account_status(%User{local: true, is_confirmed: false}), do: :confirmation_pending def account_status(%User{local: true, is_confirmed: false}), do: :confirmation_pending
@ -378,11 +380,6 @@ defmodule Pleroma.User do
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
def ap_following(%User{} = user), do: "#{ap_id(user)}/following" def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
@spec restrict_deactivated(Ecto.Query.t()) :: Ecto.Query.t()
def restrict_deactivated(query) do
from(u in query, where: u.deactivated != ^true)
end
defp truncate_fields_param(params) do defp truncate_fields_param(params) do
if Map.has_key?(params, :fields) do if Map.has_key?(params, :fields) do
Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1)) Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
@ -777,7 +774,7 @@ defmodule Pleroma.User do
candidates = Config.get([:instance, :autofollowed_nicknames]) candidates = Config.get([:instance, :autofollowed_nicknames])
autofollowed_users = autofollowed_users =
User.Query.build(%{nickname: candidates, local: true, deactivated: false}) User.Query.build(%{nickname: candidates, local: true, is_active: true})
|> Repo.all() |> Repo.all()
follow_all(user, autofollowed_users) follow_all(user, autofollowed_users)
@ -801,7 +798,7 @@ defmodule Pleroma.User do
end end
def post_register_action(%User{is_confirmed: false} = user) do def post_register_action(%User{is_confirmed: false} = user) do
with {:ok, _} <- try_send_confirmation_email(user) do with {:ok, _} <- maybe_send_confirmation_email(user) do
{:ok, user} {:ok, user}
end end
end end
@ -817,9 +814,10 @@ defmodule Pleroma.User do
with {:ok, user} <- autofollow_users(user), with {:ok, user} <- autofollow_users(user),
{:ok, _} <- autofollowing_users(user), {:ok, _} <- autofollowing_users(user),
{:ok, user} <- set_cache(user), {:ok, user} <- set_cache(user),
{:ok, _} <- send_welcome_email(user), {:ok, _} <- maybe_send_registration_email(user),
{:ok, _} <- send_welcome_message(user), {:ok, _} <- maybe_send_welcome_email(user),
{:ok, _} <- send_welcome_chat_message(user) do {:ok, _} <- maybe_send_welcome_message(user),
{:ok, _} <- maybe_send_welcome_chat_message(user) do
{:ok, user} {:ok, user}
end end
end end
@ -844,7 +842,7 @@ defmodule Pleroma.User do
{:ok, :enqueued} {:ok, :enqueued}
end end
def send_welcome_message(user) do defp maybe_send_welcome_message(user) do
if User.WelcomeMessage.enabled?() do if User.WelcomeMessage.enabled?() do
User.WelcomeMessage.post_message(user) User.WelcomeMessage.post_message(user)
{:ok, :enqueued} {:ok, :enqueued}
@ -853,7 +851,7 @@ defmodule Pleroma.User do
end end
end end
def send_welcome_chat_message(user) do defp maybe_send_welcome_chat_message(user) do
if User.WelcomeChatMessage.enabled?() do if User.WelcomeChatMessage.enabled?() do
User.WelcomeChatMessage.post_message(user) User.WelcomeChatMessage.post_message(user)
{:ok, :enqueued} {:ok, :enqueued}
@ -862,7 +860,7 @@ defmodule Pleroma.User do
end end
end end
def send_welcome_email(%User{email: email} = user) when is_binary(email) do defp maybe_send_welcome_email(%User{email: email} = user) when is_binary(email) do
if User.WelcomeEmail.enabled?() do if User.WelcomeEmail.enabled?() do
User.WelcomeEmail.send_email(user) User.WelcomeEmail.send_email(user)
{:ok, :enqueued} {:ok, :enqueued}
@ -871,10 +869,10 @@ defmodule Pleroma.User do
end end
end end
def send_welcome_email(_), do: {:ok, :noop} defp maybe_send_welcome_email(_), do: {:ok, :noop}
@spec try_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop} @spec maybe_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop}
def try_send_confirmation_email(%User{is_confirmed: false, email: email} = user) def maybe_send_confirmation_email(%User{is_confirmed: false, email: email} = user)
when is_binary(email) do when is_binary(email) do
if Config.get([:instance, :account_activation_required]) do if Config.get([:instance, :account_activation_required]) do
send_confirmation_email(user) send_confirmation_email(user)
@ -884,7 +882,7 @@ defmodule Pleroma.User do
end end
end end
def try_send_confirmation_email(_), do: {:ok, :noop} def maybe_send_confirmation_email(_), do: {:ok, :noop}
@spec send_confirmation_email(Uset.t()) :: User.t() @spec send_confirmation_email(Uset.t()) :: User.t()
def send_confirmation_email(%User{} = user) do def send_confirmation_email(%User{} = user) do
@ -895,6 +893,24 @@ defmodule Pleroma.User do
user user
end end
@spec maybe_send_registration_email(User.t()) :: {:ok, :enqueued | :noop}
defp maybe_send_registration_email(%User{email: email} = user) when is_binary(email) do
with false <- User.WelcomeEmail.enabled?(),
false <- Config.get([:instance, :account_activation_required], false),
false <- Config.get([:instance, :account_approval_required], false) do
user
|> Pleroma.Emails.UserEmail.successful_registration_email()
|> Pleroma.Emails.Mailer.deliver_async()
{:ok, :enqueued}
else
_ ->
{:ok, :noop}
end
end
defp maybe_send_registration_email(_), do: {:ok, :noop}
def needs_update?(%User{local: true}), do: false def needs_update?(%User{local: true}), do: false
def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true
@ -938,7 +954,7 @@ defmodule Pleroma.User do
deny_follow_blocked = Config.get([:user, :deny_follow_blocked]) deny_follow_blocked = Config.get([:user, :deny_follow_blocked])
cond do cond do
followed.deactivated -> not followed.is_active ->
{:error, "Could not follow user: #{followed.nickname} is deactivated."} {:error, "Could not follow user: #{followed.nickname} is deactivated."}
deny_follow_blocked and blocks?(followed, follower) -> deny_follow_blocked and blocks?(followed, follower) ->
@ -1173,7 +1189,7 @@ defmodule Pleroma.User do
@spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t() @spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
def get_followers_query(%User{} = user, nil) do def get_followers_query(%User{} = user, nil) do
User.Query.build(%{followers: user, deactivated: false}) User.Query.build(%{followers: user, is_active: true})
end end
def get_followers_query(%User{} = user, page) do def get_followers_query(%User{} = user, page) do
@ -1349,7 +1365,7 @@ defmodule Pleroma.User do
@spec get_users_from_set([String.t()], keyword()) :: [User.t()] @spec get_users_from_set([String.t()], keyword()) :: [User.t()]
def get_users_from_set(ap_ids, opts \\ []) do def get_users_from_set(ap_ids, opts \\ []) do
local_only = Keyword.get(opts, :local_only, true) local_only = Keyword.get(opts, :local_only, true)
criteria = %{ap_id: ap_ids, deactivated: false} criteria = %{ap_id: ap_ids, is_active: true}
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria
User.Query.build(criteria) User.Query.build(criteria)
@ -1360,7 +1376,7 @@ defmodule Pleroma.User do
def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do
to = [actor | to] to = [actor | to]
query = User.Query.build(%{recipients_from_activity: to, local: true, deactivated: false}) query = User.Query.build(%{recipients_from_activity: to, local: true, is_active: true})
query query
|> Repo.all() |> Repo.all()
@ -1579,19 +1595,19 @@ defmodule Pleroma.User do
defp maybe_filter_on_ap_id(query, _ap_ids), do: query defp maybe_filter_on_ap_id(query, _ap_ids), do: query
def deactivate_async(user, status \\ true) do def set_activation_async(user, status \\ true) do
BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status}) BackgroundWorker.enqueue("user_activation", %{"user_id" => user.id, "status" => status})
end end
def deactivate(user, status \\ true) @spec set_activation([User.t()], boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
def set_activation(users, status) when is_list(users) do
def deactivate(users, status) when is_list(users) do
Repo.transaction(fn -> Repo.transaction(fn ->
for user <- users, do: deactivate(user, status) for user <- users, do: set_activation(user, status)
end) end)
end end
def deactivate(%User{} = user, status) do @spec set_activation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
def set_activation(%User{} = user, status) do
with {:ok, user} <- set_activation_status(user, status) do with {:ok, user} <- set_activation_status(user, status) do
user user
|> get_followers() |> get_followers()
@ -1680,7 +1696,7 @@ defmodule Pleroma.User do
registration_reason: nil, registration_reason: nil,
confirmation_token: nil, confirmation_token: nil,
domain_blocks: [], domain_blocks: [],
deactivated: true, is_active: false,
ap_enabled: false, ap_enabled: false,
is_moderator: false, is_moderator: false,
is_admin: false, is_admin: false,
@ -1754,7 +1770,7 @@ defmodule Pleroma.User do
delete_or_deactivate(user) delete_or_deactivate(user)
end end
def perform(:deactivate_async, user, status), do: deactivate(user, status) def perform(:set_activation_async, user, status), do: set_activation(user, status)
@spec external_users_query() :: Ecto.Query.t() @spec external_users_query() :: Ecto.Query.t()
def external_users_query do def external_users_query do
@ -2034,6 +2050,15 @@ defmodule Pleroma.User do
|> hd() |> hd()
end end
def full_nickname(%User{} = user) do
if String.contains?(user.nickname, "@") do
user.nickname
else
%{host: host} = URI.parse(user.ap_id)
user.nickname <> "@" <> host
end
end
def full_nickname(nickname_or_mention), def full_nickname(nickname_or_mention),
do: String.trim_leading(nickname_or_mention, "@") do: String.trim_leading(nickname_or_mention, "@")
@ -2048,7 +2073,7 @@ defmodule Pleroma.User do
@spec all_superusers() :: [User.t()] @spec all_superusers() :: [User.t()]
def all_superusers do def all_superusers do
User.Query.build(%{super_users: true, local: true, deactivated: false}) User.Query.build(%{super_users: true, local: true, is_active: true})
|> Repo.all() |> Repo.all()
end end
@ -2089,7 +2114,7 @@ defmodule Pleroma.User do
left_join: a in Pleroma.Activity, left_join: a in Pleroma.Activity,
on: u.ap_id == a.actor, on: u.ap_id == a.actor,
where: not is_nil(u.nickname), where: not is_nil(u.nickname),
where: u.deactivated != ^true, where: u.is_active == ^true,
where: u.id not in ^has_read_notifications, where: u.id not in ^has_read_notifications,
group_by: u.id, group_by: u.id,
having: having:
@ -2210,9 +2235,9 @@ defmodule Pleroma.User do
end end
# Internal function; public one is `deactivate/2` # Internal function; public one is `deactivate/2`
defp set_activation_status(user, deactivated) do defp set_activation_status(user, status) do
user user
|> cast(%{deactivated: deactivated}, [:deactivated]) |> cast(%{is_active: status}, [:is_active])
|> update_and_set_cache() |> update_and_set_cache()
end end
@ -2448,4 +2473,19 @@ defmodule Pleroma.User do
def get_host(%User{ap_id: ap_id} = _user) do def get_host(%User{ap_id: ap_id} = _user) do
URI.parse(ap_id).host URI.parse(ap_id).host
end end
def update_last_active_at(%__MODULE__{local: true} = user) do
user
|> cast(%{last_active_at: NaiveDateTime.utc_now()}, [:last_active_at])
|> update_and_set_cache()
end
def active_user_count(weeks \\ 4) do
active_after = Timex.shift(NaiveDateTime.utc_now(), weeks: -weeks)
__MODULE__
|> where([u], u.last_active_at >= ^active_after)
|> where([u], u.local == true)
|> Repo.aggregate(:count)
end
end end

View file

@ -137,7 +137,7 @@ defmodule Pleroma.User.Query do
defp compose_query({:external, _}, query), do: location_query(query, false) defp compose_query({:external, _}, query), do: location_query(query, false)
defp compose_query({:active, _}, query) do defp compose_query({:active, _}, query) do
User.restrict_deactivated(query) where(query, [u], u.is_active == true)
|> where([u], u.is_approved == true) |> where([u], u.is_approved == true)
|> where([u], u.is_confirmed == true) |> where([u], u.is_confirmed == true)
end end
@ -148,11 +148,11 @@ defmodule Pleroma.User.Query do
end end
defp compose_query({:deactivated, false}, query) do defp compose_query({:deactivated, false}, query) do
User.restrict_deactivated(query) where(query, [u], u.is_active == true)
end end
defp compose_query({:deactivated, true}, query) do defp compose_query({:deactivated, true}, query) do
where(query, [u], u.deactivated == ^true) where(query, [u], u.is_active == false)
end end
defp compose_query({:confirmation_pending, bool}, query) do defp compose_query({:confirmation_pending, bool}, query) do

View file

@ -56,7 +56,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp check_actor_is_active(actor) when is_binary(actor) do defp check_actor_is_active(actor) when is_binary(actor) do
case User.get_cached_by_ap_id(actor) do case User.get_cached_by_ap_id(actor) do
%User{deactivated: deactivated} -> not deactivated %User{is_active: true} -> true
_ -> false _ -> false
end end
end end
@ -377,6 +377,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
:ok <- :ok <-
maybe_federate(stripped_activity) do maybe_federate(stripped_activity) do
User.all_superusers() User.all_superusers()
|> Enum.filter(fn user -> user.ap_id != actor end)
|> Enum.filter(fn user -> not is_nil(user.email) end) |> Enum.filter(fn user -> not is_nil(user.email) end)
|> Enum.each(fn superuser -> |> Enum.each(fn superuser ->
superuser superuser
@ -591,7 +592,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Enum.reverse() |> Enum.reverse()
end end
def fetch_user_activities(user, reading_user, params \\ %{}) do def fetch_user_activities(user, reading_user, params \\ %{})
def fetch_user_activities(user, reading_user, %{total: true} = params) do
result = fetch_activities_for_user(user, reading_user, params)
Keyword.put(result, :items, Enum.reverse(result[:items]))
end
def fetch_user_activities(user, reading_user, params) do
user
|> fetch_activities_for_user(reading_user, params)
|> Enum.reverse()
end
defp fetch_activities_for_user(user, reading_user, params) do
params = params =
params params
|> Map.put(:type, ["Create", "Announce"]) |> Map.put(:type, ["Create", "Announce"])
@ -616,10 +631,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
} }
|> user_activities_recipients() |> user_activities_recipients()
|> fetch_activities(params, pagination_type) |> fetch_activities(params, pagination_type)
|> Enum.reverse() end
def fetch_statuses(reading_user, %{total: true} = params) do
result = fetch_activities_for_reading_user(reading_user, params)
Keyword.put(result, :items, Enum.reverse(result[:items]))
end end
def fetch_statuses(reading_user, params) do def fetch_statuses(reading_user, params) do
reading_user
|> fetch_activities_for_reading_user(params)
|> Enum.reverse()
end
defp fetch_activities_for_reading_user(reading_user, params) do
params = Map.put(params, :type, ["Create", "Announce"]) params = Map.put(params, :type, ["Create", "Announce"])
%{ %{
@ -628,7 +653,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
} }
|> user_activities_recipients() |> user_activities_recipients()
|> fetch_activities(params, :offset) |> fetch_activities(params, :offset)
|> Enum.reverse()
end end
defp user_activities_recipients(%{godmode: true}), do: [] defp user_activities_recipients(%{godmode: true}), do: []
@ -735,6 +759,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_local(query, _), do: query defp restrict_local(query, _), do: query
defp restrict_remote(query, %{remote: true}) do
from(activity in query, where: activity.local == false)
end
defp restrict_remote(query, _), do: query
defp restrict_actor(query, %{actor_id: actor_id}) do defp restrict_actor(query, %{actor_id: actor_id}) do
from(activity in query, where: activity.actor == ^actor_id) from(activity in query, where: activity.actor == ^actor_id)
end end
@ -1111,6 +1141,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> restrict_tag_all(opts) |> restrict_tag_all(opts)
|> restrict_since(opts) |> restrict_since(opts)
|> restrict_local(opts) |> restrict_local(opts)
|> restrict_remote(opts)
|> restrict_actor(opts) |> restrict_actor(opts)
|> restrict_type(opts) |> restrict_type(opts)
|> restrict_state(opts) |> restrict_state(opts)

View file

@ -79,11 +79,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
end end
end end
def object(conn, _) do def object(%{assigns: assigns} = conn, _) do
with ap_id <- Endpoint.url() <> conn.request_path, with ap_id <- Endpoint.url() <> conn.request_path,
%Object{} = object <- Object.get_cached_by_ap_id(ap_id), %Object{} = object <- Object.get_cached_by_ap_id(ap_id),
{_, true} <- {:public?, Visibility.is_public?(object)}, user <- Map.get(assigns, :user, nil),
{_, false} <- {:local?, Visibility.is_local_public?(object)} do {_, true} <- {:visible?, Visibility.visible_for_user?(object, user)} do
conn conn
|> assign(:tracking_fun_data, object.id) |> assign(:tracking_fun_data, object.id)
|> set_cache_ttl_for(object) |> set_cache_ttl_for(object)
@ -91,11 +91,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|> put_view(ObjectView) |> put_view(ObjectView)
|> render("object.json", object: object) |> render("object.json", object: object)
else else
{:public?, false} -> {:visible?, false} -> {:error, :not_found}
{:error, :not_found} nil -> {:error, :not_found}
{:local?, true} ->
{:error, :not_found}
end end
end end
@ -109,11 +106,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
conn conn
end end
def activity(conn, _params) do def activity(%{assigns: assigns} = conn, _) do
with ap_id <- Endpoint.url() <> conn.request_path, with ap_id <- Endpoint.url() <> conn.request_path,
%Activity{} = activity <- Activity.normalize(ap_id), %Activity{} = activity <- Activity.normalize(ap_id),
{_, true} <- {:public?, Visibility.is_public?(activity)}, {_, true} <- {:local?, activity.local},
{_, false} <- {:local?, Visibility.is_local_public?(activity)} do user <- Map.get(assigns, :user, nil),
{_, true} <- {:visible?, Visibility.visible_for_user?(activity, user)} do
conn conn
|> maybe_set_tracking_data(activity) |> maybe_set_tracking_data(activity)
|> set_cache_ttl_for(activity) |> set_cache_ttl_for(activity)
@ -121,8 +119,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|> put_view(ObjectView) |> put_view(ObjectView)
|> render("object.json", object: activity) |> render("object.json", object: activity)
else else
{:public?, false} -> {:error, :not_found} {:visible?, false} -> {:error, :not_found}
{:local?, true} -> {:error, :not_found} {:local?, false} -> {:error, :not_found}
nil -> {:error, :not_found} nil -> {:error, :not_found}
end end
end end

View file

@ -0,0 +1,61 @@
# 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.MRF.NoEmptyPolicy do
@moduledoc "Filter local activities which have no content"
@behaviour Pleroma.Web.ActivityPub.MRF
alias Pleroma.Web
@impl true
def filter(%{"actor" => actor} = object) do
with true <- is_local?(actor),
true <- is_note?(object),
false <- has_attachment?(object),
true <- only_mentions?(object) do
{:reject, "[NoEmptyPolicy]"}
else
_ ->
{:ok, object}
end
end
def filter(object), do: {:ok, object}
defp is_local?(actor) do
if actor |> String.starts_with?("#{Web.base_url()}") do
true
else
false
end
end
defp has_attachment?(%{
"type" => "Create",
"object" => %{"type" => "Note", "attachment" => attachments}
})
when length(attachments) > 0,
do: true
defp has_attachment?(_), do: false
defp only_mentions?(%{"type" => "Create", "object" => %{"type" => "Note", "source" => source}}) do
non_mentions =
source |> String.split() |> Enum.filter(&(not String.starts_with?(&1, "@"))) |> length
if non_mentions > 0 do
false
else
true
end
end
defp only_mentions?(_), do: false
defp is_note?(%{"type" => "Create", "object" => %{"type" => "Note"}}), do: true
defp is_note?(_), do: false
@impl true
def describe, do: {:ok, %{}}
end

View file

@ -35,7 +35,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do
cng cng
|> validate_change(field_name, fn field_name, actor -> |> validate_change(field_name, fn field_name, actor ->
case User.get_cached_by_ap_id(actor) do case User.get_cached_by_ap_id(actor) do
%User{deactivated: true} -> %User{is_active: false} ->
[{field_name, "user is deactivated"}] [{field_name, "user is deactivated"}]
%User{} -> %User{} ->

View file

@ -56,11 +56,10 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
def is_list?(%{data: %{"listMessage" => _}}), do: true def is_list?(%{data: %{"listMessage" => _}}), do: true
def is_list?(_), do: false def is_list?(_), do: false
@spec visible_for_user?(Activity.t() | nil, User.t() | nil) :: boolean() @spec visible_for_user?(Object.t() | Activity.t() | nil, User.t() | nil) :: boolean()
def visible_for_user?(%Activity{actor: ap_id}, %User{ap_id: ap_id}), do: true def visible_for_user?(%Activity{actor: ap_id}, %User{ap_id: ap_id}), do: true
def visible_for_user?(%Object{data: %{"actor" => ap_id}}, %User{ap_id: ap_id}), do: true
def visible_for_user?(nil, _), do: false def visible_for_user?(nil, _), do: false
def visible_for_user?(%Activity{data: %{"listMessage" => _}}, nil), do: false def visible_for_user?(%Activity{data: %{"listMessage" => _}}, nil), do: false
def visible_for_user?( def visible_for_user?(
@ -73,16 +72,18 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
|> Pleroma.List.member?(user) |> Pleroma.List.member?(user)
end end
def visible_for_user?(%Activity{} = activity, nil) do def visible_for_user?(%{__struct__: module} = message, nil)
if restrict_unauthenticated_access?(activity), when module in [Activity, Object] do
if restrict_unauthenticated_access?(message),
do: false, do: false,
else: is_public?(activity) else: is_public?(message) and not is_local_public?(message)
end end
def visible_for_user?(%Activity{} = activity, user) do def visible_for_user?(%{__struct__: module} = message, user)
when module in [Activity, Object] do
x = [user.ap_id | User.following(user)] x = [user.ap_id | User.following(user)]
y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || []) y = [message.data["actor"]] ++ message.data["to"] ++ (message.data["cc"] || [])
is_public?(activity) || Enum.any?(x, &(&1 in y)) is_public?(message) || Enum.any?(x, &(&1 in y))
end end
def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do

View file

@ -25,13 +25,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:accounts"], admin: true} %{scopes: ["admin:read:accounts"]}
when action in [:right_get, :show_user_credentials, :create_backup] when action in [:right_get, :show_user_credentials, :create_backup]
) )
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:accounts"], admin: true} %{scopes: ["admin:write:accounts"]}
when action in [ when action in [
:get_password_reset, :get_password_reset,
:force_password_reset, :force_password_reset,
@ -48,19 +48,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:statuses"], admin: true} %{scopes: ["admin:read:statuses"]}
when action in [:list_user_statuses, :list_instance_statuses] when action in [:list_user_statuses, :list_instance_statuses]
) )
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:chats"], admin: true} %{scopes: ["admin:read:chats"]}
when action in [:list_user_chats] when action in [:list_user_chats]
) )
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read"], admin: true} %{scopes: ["admin:read"]}
when action in [ when action in [
:list_log, :list_log,
:stats, :stats,
@ -70,7 +70,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write"], admin: true} %{scopes: ["admin:write"]}
when action in [ when action in [
:restart, :restart,
:resend_confirmation_email, :resend_confirmation_email,
@ -85,17 +85,18 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
{page, page_size} = page_params(params) {page, page_size} = page_params(params)
activities = result =
ActivityPub.fetch_statuses(nil, %{ ActivityPub.fetch_statuses(nil, %{
instance: instance, instance: instance,
limit: page_size, limit: page_size,
offset: (page - 1) * page_size, offset: (page - 1) * page_size,
exclude_reblogs: not with_reblogs exclude_reblogs: not with_reblogs,
total: true
}) })
conn conn
|> put_view(AdminAPI.StatusView) |> put_view(AdminAPI.StatusView)
|> render("index.json", %{activities: activities, as: :activity}) |> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
end end
def list_user_statuses(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname} = params) do def list_user_statuses(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname} = params) do
@ -105,18 +106,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname, for: admin) do with %User{} = user <- User.get_cached_by_nickname_or_id(nickname, for: admin) do
{page, page_size} = page_params(params) {page, page_size} = page_params(params)
activities = result =
ActivityPub.fetch_user_activities(user, nil, %{ ActivityPub.fetch_user_activities(user, nil, %{
limit: page_size, limit: page_size,
offset: (page - 1) * page_size, offset: (page - 1) * page_size,
godmode: godmode, godmode: godmode,
exclude_reblogs: not with_reblogs, exclude_reblogs: not with_reblogs,
pagination_type: :offset pagination_type: :offset,
total: true
}) })
conn conn
|> put_view(AdminAPI.StatusView) |> put_view(AdminAPI.StatusView)
|> render("index.json", %{activities: activities, as: :activity}) |> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
else else
_ -> {:error, :not_found} _ -> {:error, :not_found}
end end
@ -404,7 +406,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
if Config.get(:configurable_from_database) do if Config.get(:configurable_from_database) do
:ok :ok
else else
{:error, "To use this endpoint you need to enable configuration from database."} {:error, "You must enable configurable_from_database in your config file."}
end end
end end

View file

@ -21,12 +21,12 @@ defmodule Pleroma.Web.AdminAPI.ChatController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:chats"], admin: true} when action in [:show, :messages] %{scopes: ["admin:read:chats"]} when action in [:show, :messages]
) )
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:chats"], admin: true} when action in [:delete_message] %{scopes: ["admin:write:chats"]} when action in [:delete_message]
) )
action_fallback(Pleroma.Web.AdminAPI.FallbackController) action_fallback(Pleroma.Web.AdminAPI.FallbackController)

View file

@ -10,11 +10,11 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :update) plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :update)
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read"], admin: true} %{scopes: ["admin:read"]}
when action in [:show, :descriptions] when action in [:show, :descriptions]
) )
@ -122,7 +122,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
if Config.get(:configurable_from_database) do if Config.get(:configurable_from_database) do
:ok :ok
else else
{:error, "To use this endpoint you need to enable configuration from database."} {:error, "You must enable configurable_from_database in your config file."}
end end
end end

View file

@ -9,8 +9,8 @@ defmodule Pleroma.Web.AdminAPI.FrontendController do
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :install) plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :install)
plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :index) plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :index)
action_fallback(Pleroma.Web.AdminAPI.FallbackController) action_fallback(Pleroma.Web.AdminAPI.FallbackController)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.FrontendOperation defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.FrontendOperation

View file

@ -15,8 +15,8 @@ defmodule Pleroma.Web.AdminAPI.InstanceDocumentController do
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation
plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :show) plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :show)
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action in [:update, :delete]) plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action in [:update, :delete])
def show(conn, %{name: document_name}) do def show(conn, %{name: document_name}) do
with {:ok, url} <- InstanceDocument.get(document_name), with {:ok, url} <- InstanceDocument.get(document_name),

View file

@ -14,11 +14,11 @@ defmodule Pleroma.Web.AdminAPI.InviteController do
require Logger require Logger
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["read:invites"], admin: true} when action == :index) plug(OAuthScopesPlug, %{scopes: ["admin:read:invites"]} when action == :index)
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:invites"], admin: true} when action in [:create, :revoke, :email] %{scopes: ["admin:write:invites"]} when action in [:create, :revoke, :email]
) )
action_fallback(Pleroma.Web.AdminAPI.FallbackController) action_fallback(Pleroma.Web.AdminAPI.FallbackController)

View file

@ -15,12 +15,12 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:media_proxy_caches"], admin: true} when action in [:index] %{scopes: ["admin:read:media_proxy_caches"]} when action in [:index]
) )
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:media_proxy_caches"], admin: true} when action in [:purge, :delete] %{scopes: ["admin:write:media_proxy_caches"]} when action in [:purge, :delete]
) )
action_fallback(Pleroma.Web.AdminAPI.FallbackController) action_fallback(Pleroma.Web.AdminAPI.FallbackController)

View file

@ -17,7 +17,7 @@ defmodule Pleroma.Web.AdminAPI.OAuthAppController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write"], admin: true} %{scopes: ["admin:write"]}
when action in [:create, :index, :update, :delete] when action in [:create, :index, :update, :delete]
) )

View file

@ -15,11 +15,11 @@ defmodule Pleroma.Web.AdminAPI.RelayController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:follows"], admin: true} %{scopes: ["admin:write:follows"]}
when action in [:follow, :unfollow] when action in [:follow, :unfollow]
) )
plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :index) plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :index)
action_fallback(Pleroma.Web.AdminAPI.FallbackController) action_fallback(Pleroma.Web.AdminAPI.FallbackController)

View file

@ -19,11 +19,11 @@ defmodule Pleroma.Web.AdminAPI.ReportController do
require Logger require Logger
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["read:reports"], admin: true} when action in [:index, :show]) plug(OAuthScopesPlug, %{scopes: ["admin:read:reports"]} when action in [:index, :show])
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:reports"], admin: true} %{scopes: ["admin:write:reports"]}
when action in [:update, :notes_create, :notes_delete] when action in [:update, :notes_create, :notes_delete]
) )

View file

@ -15,11 +15,11 @@ defmodule Pleroma.Web.AdminAPI.StatusController do
require Logger require Logger
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["read:statuses"], admin: true} when action in [:index, :show]) plug(OAuthScopesPlug, %{scopes: ["admin:read:statuses"]} when action in [:index, :show])
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:statuses"], admin: true} when action in [:update, :delete] %{scopes: ["admin:write:statuses"]} when action in [:update, :delete]
) )
action_fallback(Pleroma.Web.AdminAPI.FallbackController) action_fallback(Pleroma.Web.AdminAPI.FallbackController)

View file

@ -21,13 +21,13 @@ defmodule Pleroma.Web.AdminAPI.UserController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:accounts"], admin: true} %{scopes: ["admin:read:accounts"]}
when action in [:list, :show] when action in [:list, :show]
) )
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:accounts"], admin: true} %{scopes: ["admin:write:accounts"]}
when action in [ when action in [
:delete, :delete,
:create, :create,
@ -40,7 +40,7 @@ defmodule Pleroma.Web.AdminAPI.UserController do
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:follows"], admin: true} %{scopes: ["admin:write:follows"]}
when action in [:follow, :unfollow] when action in [:follow, :unfollow]
) )
@ -172,9 +172,9 @@ defmodule Pleroma.Web.AdminAPI.UserController do
def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
user = User.get_cached_by_nickname(nickname) user = User.get_cached_by_nickname(nickname)
{:ok, updated_user} = User.deactivate(user, !user.deactivated) {:ok, updated_user} = User.set_activation(user, !user.is_active)
action = if user.deactivated, do: "activate", else: "deactivate" action = if !user.is_active, do: "activate", else: "deactivate"
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
actor: admin, actor: admin,
@ -189,7 +189,7 @@ defmodule Pleroma.Web.AdminAPI.UserController do
def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
users = Enum.map(nicknames, &User.get_cached_by_nickname/1) users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
{:ok, updated_users} = User.deactivate(users, false) {:ok, updated_users} = User.set_activation(users, true)
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
actor: admin, actor: admin,
@ -204,7 +204,7 @@ defmodule Pleroma.Web.AdminAPI.UserController do
def deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do def deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
users = Enum.map(nicknames, &User.get_cached_by_nickname/1) users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
{:ok, updated_users} = User.deactivate(users, true) {:ok, updated_users} = User.set_activation(users, false)
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
actor: admin, actor: admin,

View file

@ -73,7 +73,7 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
"avatar" => avatar, "avatar" => avatar,
"nickname" => user.nickname, "nickname" => user.nickname,
"display_name" => display_name, "display_name" => display_name,
"deactivated" => user.deactivated, "is_active" => user.is_active,
"local" => user.local, "local" => user.local,
"roles" => User.roles(user), "roles" => User.roles(user),
"tags" => user.tags || [], "tags" => user.tags || [],

View file

@ -13,6 +13,10 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
defdelegate merge_account_views(user), to: AdminAPI.AccountView defdelegate merge_account_views(user), to: AdminAPI.AccountView
def render("index.json", %{total: total} = opts) do
%{total: total, activities: safe_render_many(opts.activities, __MODULE__, "show.json", opts)}
end
def render("index.json", opts) do def render("index.json", opts) do
safe_render_many(opts.activities, __MODULE__, "show.json", opts) safe_render_many(opts.activities, __MODULE__, "show.json", opts)
end end

View file

@ -11,10 +11,10 @@ defmodule Pleroma.Web.ApiSpec do
@behaviour OpenApi @behaviour OpenApi
@impl OpenApi @impl OpenApi
def spec do def spec(opts \\ []) do
%OpenApi{ %OpenApi{
servers: servers:
if Phoenix.Endpoint.server?(:pleroma, Endpoint) do if opts[:server_specific] do
[ [
# Populate the Server info from a phoenix endpoint # Populate the Server info from a phoenix endpoint
OpenApiSpex.Server.from_endpoint(Endpoint) OpenApiSpex.Server.from_endpoint(Endpoint)
@ -23,9 +23,26 @@ defmodule Pleroma.Web.ApiSpec do
[] []
end, end,
info: %OpenApiSpex.Info{ info: %OpenApiSpex.Info{
title: "Pleroma", title: "Pleroma API",
description: Application.spec(:pleroma, :description) |> to_string(), description: """
version: Application.spec(:pleroma, :vsn) |> to_string() This is documentation for client Pleroma API. Most of the endpoints and entities come
from Mastodon API and have custom extensions on top.
While this document aims to be a complete guide to the client API Pleroma exposes,
the details are still being worked out. Some endpoints may have incomplete or poorly worded documentation.
You might want to check the following resources if something is not clear:
- [Legacy Pleroma-specific endpoint documentation](https://docs-develop.pleroma.social/backend/development/API/pleroma_api/)
- [Mastodon API documentation](https://docs.joinmastodon.org/client/intro/)
- [Differences in Mastodon API responses from vanilla Mastodon](https://docs-develop.pleroma.social/backend/development/API/differences_in_mastoapi_responses/)
Please report such occurences on our [issue tracker](https://git.pleroma.social/pleroma/pleroma/-/issues). Feel free to submit API questions or proposals there too!
""",
# Strip environment from the version
version: Application.spec(:pleroma, :vsn) |> to_string() |> String.replace(~r/\+.*$/, ""),
extensions: %{
# Logo path should be picked so that the path exists both on Pleroma instances and on api.pleroma.social
"x-logo": %{"url" => "/static/logo.svg", "altText" => "Pleroma logo"}
}
}, },
# populate the paths from a phoenix router # populate the paths from a phoenix router
paths: OpenApiSpex.Paths.from_router(Router), paths: OpenApiSpex.Paths.from_router(Router),
@ -45,15 +62,73 @@ defmodule Pleroma.Web.ApiSpec do
authorizationUrl: "/oauth/authorize", authorizationUrl: "/oauth/authorize",
tokenUrl: "/oauth/token", tokenUrl: "/oauth/token",
scopes: %{ scopes: %{
"read" => "read", # TODO: Document granular scopes
"write" => "write", "read" => "Read everything",
"follow" => "follow", "write" => "Write everything",
"push" => "push" "follow" => "Manage relationships",
"push" => "Web Push API subscriptions"
} }
} }
} }
} }
} }
},
extensions: %{
# Redoc-specific extension, every time a new tag is added it should be reflected here,
# otherwise it won't be shown.
"x-tagGroups": [
%{
"name" => "Accounts",
"tags" => ["Account actions", "Retrieve account information", "Scrobbles"]
},
%{
"name" => "Administration",
"tags" => [
"Chat administration",
"Emoji pack administration",
"Frontend managment",
"Instance configuration",
"Instance documents",
"Invites",
"MediaProxy cache",
"OAuth application managment",
"Report managment",
"Relays",
"Status administration"
]
},
%{"name" => "Applications", "tags" => ["Applications", "Push subscriptions"]},
%{
"name" => "Current account",
"tags" => [
"Account credentials",
"Backups",
"Blocks and mutes",
"Data import",
"Domain blocks",
"Follow requests",
"Mascot",
"Markers",
"Notifications"
]
},
%{"name" => "Instance", "tags" => ["Custom emojis"]},
%{"name" => "Messaging", "tags" => ["Chats", "Conversations"]},
%{
"name" => "Statuses",
"tags" => [
"Emoji reactions",
"Lists",
"Polls",
"Timelines",
"Retrieve status information",
"Scheduled statuses",
"Search",
"Status actions"
]
},
%{"name" => "Miscellaneous", "tags" => ["Emoji packs", "Reports", "Suggestions"]}
]
} }
} }
# discover request/response schemas from path specs # discover request/response schemas from path specs

View file

@ -63,7 +63,7 @@ defmodule Pleroma.Web.ApiSpec.Helpers do
:with_relationships, :with_relationships,
:query, :query,
BooleanLike, BooleanLike,
"Embed relationships into accounts." "Embed relationships into accounts. **If this parameter is not set account's `pleroma.relationship` is going to be `null`.**"
) )
end end

View file

@ -26,7 +26,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
@spec create_operation() :: Operation.t() @spec create_operation() :: Operation.t()
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account credentials"],
summary: "Register an account", summary: "Register an account",
description: description:
"Creates a user and account records. Returns an account access token for the app that initiated the request. The app should save this token for later, and should wait for the user to confirm their account by clicking a link in their email inbox.", "Creates a user and account records. Returns an account access token for the app that initiated the request. The app should save this token for later, and should wait for the user to confirm their account by clicking a link in their email inbox.",
@ -43,7 +43,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def verify_credentials_operation do def verify_credentials_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account credentials"],
description: "Test to make sure that the user token works.", description: "Test to make sure that the user token works.",
summary: "Verify account credentials", summary: "Verify account credentials",
operationId: "AccountController.verify_credentials", operationId: "AccountController.verify_credentials",
@ -56,7 +56,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def update_credentials_operation do def update_credentials_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account credentials"],
summary: "Update account credentials", summary: "Update account credentials",
description: "Update the user's display and preferences.", description: "Update the user's display and preferences.",
operationId: "AccountController.update_credentials", operationId: "AccountController.update_credentials",
@ -71,8 +71,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def relationships_operation do def relationships_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Retrieve account information"],
summary: "Check relationships to other accounts", summary: "Relationship with current account",
operationId: "AccountController.relationships", operationId: "AccountController.relationships",
description: "Find out whether a given account is followed, blocked, muted, etc.", description: "Find out whether a given account is followed, blocked, muted, etc.",
security: [%{"oAuth" => ["read:follows"]}], security: [%{"oAuth" => ["read:follows"]}],
@ -95,11 +95,14 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Retrieve account information"],
summary: "Account", summary: "Account",
operationId: "AccountController.show", operationId: "AccountController.show",
description: "View information about a profile.", description: "View information about a profile.",
parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}], parameters: [
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
with_relationships_param()
],
responses: %{ responses: %{
200 => Operation.response("Account", "application/json", Account), 200 => Operation.response("Account", "application/json", Account),
401 => Operation.response("Error", "application/json", ApiError), 401 => Operation.response("Error", "application/json", ApiError),
@ -110,8 +113,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def statuses_operation do def statuses_operation do
%Operation{ %Operation{
tags: ["accounts"],
summary: "Statuses", summary: "Statuses",
tags: ["Retrieve account information"],
operationId: "AccountController.statuses", operationId: "AccountController.statuses",
description: description:
"Statuses posted to the given account. Public (for public statuses only), or user token + `read:statuses` (for private statuses the user is authorized to see)", "Statuses posted to the given account. Public (for public statuses only), or user token + `read:statuses` (for private statuses the user is authorized to see)",
@ -130,7 +133,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:with_muted, :with_muted,
:query, :query,
BooleanLike, BooleanLike,
"Include statuses from muted acccounts." "Include statuses from muted accounts."
), ),
Operation.parameter(:exclude_reblogs, :query, BooleanLike, "Exclude reblogs"), Operation.parameter(:exclude_reblogs, :query, BooleanLike, "Exclude reblogs"),
Operation.parameter(:exclude_replies, :query, BooleanLike, "Exclude replies"), Operation.parameter(:exclude_replies, :query, BooleanLike, "Exclude replies"),
@ -144,7 +147,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:with_muted, :with_muted,
:query, :query,
BooleanLike, BooleanLike,
"Include reactions from muted acccounts." "Include reactions from muted accounts."
) )
] ++ pagination_params(), ] ++ pagination_params(),
responses: %{ responses: %{
@ -157,7 +160,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def followers_operation do def followers_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Retrieve account information"],
summary: "Followers", summary: "Followers",
operationId: "AccountController.followers", operationId: "AccountController.followers",
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
@ -176,7 +179,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def following_operation do def following_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Retrieve account information"],
summary: "Following", summary: "Following",
operationId: "AccountController.following", operationId: "AccountController.following",
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
@ -193,7 +196,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def lists_operation do def lists_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Retrieve account information"],
summary: "Lists containing this account", summary: "Lists containing this account",
operationId: "AccountController.lists", operationId: "AccountController.lists",
security: [%{"oAuth" => ["read:lists"]}], security: [%{"oAuth" => ["read:lists"]}],
@ -205,7 +208,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def follow_operation do def follow_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account actions"],
summary: "Follow", summary: "Follow",
operationId: "AccountController.follow", operationId: "AccountController.follow",
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -238,7 +241,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def unfollow_operation do def unfollow_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account actions"],
summary: "Unfollow", summary: "Unfollow",
operationId: "AccountController.unfollow", operationId: "AccountController.unfollow",
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -254,7 +257,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def mute_operation do def mute_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account actions"],
summary: "Mute", summary: "Mute",
operationId: "AccountController.mute", operationId: "AccountController.mute",
security: [%{"oAuth" => ["follow", "write:mutes"]}], security: [%{"oAuth" => ["follow", "write:mutes"]}],
@ -284,7 +287,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def unmute_operation do def unmute_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account actions"],
summary: "Unmute", summary: "Unmute",
operationId: "AccountController.unmute", operationId: "AccountController.unmute",
security: [%{"oAuth" => ["follow", "write:mutes"]}], security: [%{"oAuth" => ["follow", "write:mutes"]}],
@ -298,7 +301,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def block_operation do def block_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account actions"],
summary: "Block", summary: "Block",
operationId: "AccountController.block", operationId: "AccountController.block",
security: [%{"oAuth" => ["follow", "write:blocks"]}], security: [%{"oAuth" => ["follow", "write:blocks"]}],
@ -313,7 +316,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def unblock_operation do def unblock_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account actions"],
summary: "Unblock", summary: "Unblock",
operationId: "AccountController.unblock", operationId: "AccountController.unblock",
security: [%{"oAuth" => ["follow", "write:blocks"]}], security: [%{"oAuth" => ["follow", "write:blocks"]}],
@ -327,7 +330,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def follow_by_uri_operation do def follow_by_uri_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Account actions"],
summary: "Follow by URI", summary: "Follow by URI",
operationId: "AccountController.follows", operationId: "AccountController.follows",
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -342,12 +345,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def mutes_operation do def mutes_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Blocks and mutes"],
summary: "Muted accounts", summary: "Retrieve list of mutes",
operationId: "AccountController.mutes", operationId: "AccountController.mutes",
description: "Accounts the user has muted.", description: "Accounts the user has muted.",
security: [%{"oAuth" => ["follow", "read:mutes"]}], security: [%{"oAuth" => ["follow", "read:mutes"]}],
parameters: pagination_params(), parameters: [with_relationships_param() | pagination_params()],
responses: %{ responses: %{
200 => Operation.response("Accounts", "application/json", array_of_accounts()) 200 => Operation.response("Accounts", "application/json", array_of_accounts())
} }
@ -356,8 +359,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def blocks_operation do def blocks_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Blocks and mutes"],
summary: "Blocked users", summary: "Retrieve list of blocks",
operationId: "AccountController.blocks", operationId: "AccountController.blocks",
description: "View your blocks. See also accounts/:id/{block,unblock}", description: "View your blocks. See also accounts/:id/{block,unblock}",
security: [%{"oAuth" => ["read:blocks"]}], security: [%{"oAuth" => ["read:blocks"]}],
@ -370,7 +373,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def endorsements_operation do def endorsements_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Retrieve account information"],
summary: "Endorsements", summary: "Endorsements",
operationId: "AccountController.endorsements", operationId: "AccountController.endorsements",
description: "Not implemented", description: "Not implemented",
@ -383,7 +386,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def identity_proofs_operation do def identity_proofs_operation do
%Operation{ %Operation{
tags: ["accounts"], tags: ["Retrieve account information"],
summary: "Identity proofs", summary: "Identity proofs",
operationId: "AccountController.identity_proofs", operationId: "AccountController.identity_proofs",
# Validators complains about unused path params otherwise # Validators complains about unused path params otherwise

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
def delete_message_operation do def delete_message_operation do
%Operation{ %Operation{
tags: ["admin", "chat"], tags: ["Chat administration"],
summary: "Delete an individual chat message", summary: "Delete an individual chat message",
operationId: "AdminAPI.ChatController.delete_message", operationId: "AdminAPI.ChatController.delete_message",
parameters: [ parameters: [
@ -33,7 +33,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
}, },
security: [ security: [
%{ %{
"oAuth" => ["write:chats"] "oAuth" => ["admin:write:chats"]
} }
] ]
} }
@ -41,8 +41,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
def messages_operation do def messages_operation do
%Operation{ %Operation{
tags: ["admin", "chat"], tags: ["Chat administration"],
summary: "Get the most recent messages of the chat", summary: "Get chat's messages",
operationId: "AdminAPI.ChatController.messages", operationId: "AdminAPI.ChatController.messages",
parameters: parameters:
[Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++ [Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++
@ -57,7 +57,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
}, },
security: [ security: [
%{ %{
"oAuth" => ["read:chats"] "oAuth" => ["admin:read:chats"]
} }
] ]
} }
@ -65,7 +65,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chat administration"],
summary: "Create a chat", summary: "Create a chat",
operationId: "AdminAPI.ChatController.show", operationId: "AdminAPI.ChatController.show",
parameters: [ parameters: [
@ -88,7 +88,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
}, },
security: [ security: [
%{ %{
"oAuth" => ["read"] "oAuth" => ["admin:read"]
} }
] ]
} }

View file

@ -16,8 +16,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Admin", "Config"], tags: ["Instance configuration"],
summary: "Get list of merged default settings with saved in database", summary: "Retrieve instance configuration",
operationId: "AdminAPI.ConfigController.show", operationId: "AdminAPI.ConfigController.show",
parameters: [ parameters: [
Operation.parameter( Operation.parameter(
@ -28,7 +28,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
) )
| admin_api_params() | admin_api_params()
], ],
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["admin:read"]}],
responses: %{ responses: %{
200 => Operation.response("Config", "application/json", config_response()), 200 => Operation.response("Config", "application/json", config_response()),
400 => Operation.response("Bad Request", "application/json", ApiError) 400 => Operation.response("Bad Request", "application/json", ApiError)
@ -38,10 +38,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Admin", "Config"], tags: ["Instance configuration"],
summary: "Update config settings", summary: "Update instance configuration",
operationId: "AdminAPI.ConfigController.update", operationId: "AdminAPI.ConfigController.update",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
@ -71,10 +71,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
def descriptions_operation do def descriptions_operation do
%Operation{ %Operation{
tags: ["Admin", "Config"], tags: ["Instance configuration"],
summary: "Get JSON with config descriptions.", summary: "Retrieve config description",
operationId: "AdminAPI.ConfigController.descriptions", operationId: "AdminAPI.ConfigController.descriptions",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["admin:read"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
responses: %{ responses: %{
200 => 200 =>

View file

@ -16,10 +16,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.FrontendOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Admin", "Reports"], tags: ["Frontend managment"],
summary: "Get a list of available frontends", summary: "Retrieve a list of available frontends",
operationId: "AdminAPI.FrontendController.index", operationId: "AdminAPI.FrontendController.index",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["admin:read"]}],
responses: %{ responses: %{
200 => Operation.response("Response", "application/json", list_of_frontends()), 200 => Operation.response("Response", "application/json", list_of_frontends()),
403 => Operation.response("Forbidden", "application/json", ApiError) 403 => Operation.response("Forbidden", "application/json", ApiError)
@ -29,10 +29,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.FrontendOperation do
def install_operation do def install_operation do
%Operation{ %Operation{
tags: ["Admin", "Reports"], tags: ["Frontend managment"],
summary: "Install a frontend", summary: "Install a frontend",
operationId: "AdminAPI.FrontendController.install", operationId: "AdminAPI.FrontendController.install",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["admin:read"]}],
requestBody: request_body("Parameters", install_request(), required: true), requestBody: request_body("Parameters", install_request(), required: true),
responses: %{ responses: %{
200 => Operation.response("Response", "application/json", list_of_frontends()), 200 => Operation.response("Response", "application/json", list_of_frontends()),

View file

@ -15,10 +15,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Admin", "InstanceDocument"], tags: ["Instance documents"],
summary: "Get the instance document", summary: "Retrieve an instance document",
operationId: "AdminAPI.InstanceDocumentController.show", operationId: "AdminAPI.InstanceDocumentController.show",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["admin:read"]}],
parameters: [ parameters: [
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name", Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
required: true required: true
@ -36,10 +36,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Admin", "InstanceDocument"], tags: ["Instance documents"],
summary: "Update the instance document", summary: "Update an instance document",
operationId: "AdminAPI.InstanceDocumentController.update", operationId: "AdminAPI.InstanceDocumentController.update",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
requestBody: Helpers.request_body("Parameters", update_request()), requestBody: Helpers.request_body("Parameters", update_request()),
parameters: [ parameters: [
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name", Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
@ -74,10 +74,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Admin", "InstanceDocument"], tags: ["Instance documents"],
summary: "Get the instance document", summary: "Delete an instance document",
operationId: "AdminAPI.InstanceDocumentController.delete", operationId: "AdminAPI.InstanceDocumentController.delete",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
parameters: [ parameters: [
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name", Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
required: true required: true

View file

@ -16,10 +16,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Admin", "Invites"], tags: ["Invites"],
summary: "Get a list of generated invites", summary: "Get a list of generated invites",
operationId: "AdminAPI.InviteController.index", operationId: "AdminAPI.InviteController.index",
security: [%{"oAuth" => ["read:invites"]}], security: [%{"oAuth" => ["admin:read:invites"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
responses: %{ responses: %{
200 => 200 =>
@ -48,10 +48,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Admin", "Invites"], tags: ["Invites"],
summary: "Create an account registration invite token", summary: "Create an account registration invite token",
operationId: "AdminAPI.InviteController.create", operationId: "AdminAPI.InviteController.create",
security: [%{"oAuth" => ["write:invites"]}], security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
@ -69,10 +69,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
def revoke_operation do def revoke_operation do
%Operation{ %Operation{
tags: ["Admin", "Invites"], tags: ["Invites"],
summary: "Revoke invite by token", summary: "Revoke invite by token",
operationId: "AdminAPI.InviteController.revoke", operationId: "AdminAPI.InviteController.revoke",
security: [%{"oAuth" => ["write:invites"]}], security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(
@ -96,10 +96,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
def email_operation do def email_operation do
%Operation{ %Operation{
tags: ["Admin", "Invites"], tags: ["Invites"],
summary: "Sends registration invite via email", summary: "Sends registration invite via email",
operationId: "AdminAPI.InviteController.email", operationId: "AdminAPI.InviteController.email",
security: [%{"oAuth" => ["write:invites"]}], security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(

View file

@ -16,10 +16,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Admin", "MediaProxyCache"], tags: ["MediaProxy cache"],
summary: "Fetch a paginated list of all banned MediaProxy URLs in Cachex", summary: "Retrieve a list of banned MediaProxy URLs",
operationId: "AdminAPI.MediaProxyCacheController.index", operationId: "AdminAPI.MediaProxyCacheController.index",
security: [%{"oAuth" => ["read:media_proxy_caches"]}], security: [%{"oAuth" => ["admin:read:media_proxy_caches"]}],
parameters: [ parameters: [
Operation.parameter( Operation.parameter(
:query, :query,
@ -44,7 +44,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
responses: %{ responses: %{
200 => 200 =>
Operation.response( Operation.response(
"Array of banned MediaProxy URLs in Cachex", "Array of MediaProxy URLs",
"application/json", "application/json",
%Schema{ %Schema{
type: :object, type: :object,
@ -68,10 +68,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Admin", "MediaProxyCache"], tags: ["MediaProxy cache"],
summary: "Remove a banned MediaProxy URL from Cachex", summary: "Remove a banned MediaProxy URL",
operationId: "AdminAPI.MediaProxyCacheController.delete", operationId: "AdminAPI.MediaProxyCacheController.delete",
security: [%{"oAuth" => ["write:media_proxy_caches"]}], security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(
@ -94,10 +94,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
def purge_operation do def purge_operation do
%Operation{ %Operation{
tags: ["Admin", "MediaProxyCache"], tags: ["MediaProxy cache"],
summary: "Purge and optionally ban a MediaProxy URL", summary: "Purge a URL from MediaProxy cache and optionally ban it",
operationId: "AdminAPI.MediaProxyCacheController.purge", operationId: "AdminAPI.MediaProxyCacheController.purge",
security: [%{"oAuth" => ["write:media_proxy_caches"]}], security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(

View file

@ -16,10 +16,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
summary: "List OAuth apps", summary: "Retrieve a list of OAuth applications",
tags: ["Admin", "oAuth Apps"], tags: ["OAuth application managment"],
operationId: "AdminAPI.OAuthAppController.index", operationId: "AdminAPI.OAuthAppController.index",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
parameters: [ parameters: [
Operation.parameter(:name, :query, %Schema{type: :string}, "App name"), Operation.parameter(:name, :query, %Schema{type: :string}, "App name"),
Operation.parameter(:client_id, :query, %Schema{type: :string}, "Client ID"), Operation.parameter(:client_id, :query, %Schema{type: :string}, "Client ID"),
@ -69,12 +69,12 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Admin", "oAuth Apps"], tags: ["OAuth application managment"],
summary: "Create OAuth App", summary: "Create an OAuth application",
operationId: "AdminAPI.OAuthAppController.create", operationId: "AdminAPI.OAuthAppController.create",
requestBody: request_body("Parameters", create_request()), requestBody: request_body("Parameters", create_request()),
parameters: admin_api_params(), parameters: admin_api_params(),
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
responses: %{ responses: %{
200 => Operation.response("App", "application/json", oauth_app()), 200 => Operation.response("App", "application/json", oauth_app()),
400 => Operation.response("Bad Request", "application/json", ApiError) 400 => Operation.response("Bad Request", "application/json", ApiError)
@ -84,11 +84,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Admin", "oAuth Apps"], tags: ["OAuth application managment"],
summary: "Update OAuth App", summary: "Update OAuth application",
operationId: "AdminAPI.OAuthAppController.update", operationId: "AdminAPI.OAuthAppController.update",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", update_request()), requestBody: request_body("Parameters", update_request()),
responses: %{ responses: %{
200 => Operation.response("App", "application/json", oauth_app()), 200 => Operation.response("App", "application/json", oauth_app()),
@ -102,11 +102,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Admin", "oAuth Apps"], tags: ["OAuth application managment"],
summary: "Delete OAuth App", summary: "Delete OAuth application",
operationId: "AdminAPI.OAuthAppController.delete", operationId: "AdminAPI.OAuthAppController.delete",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
responses: %{ responses: %{
204 => no_content_response(), 204 => no_content_response(),
400 => no_content_response() 400 => no_content_response()

View file

@ -15,10 +15,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Admin", "Relays"], tags: ["Relays"],
summary: "List Relays", summary: "Retrieve a list of relays",
operationId: "AdminAPI.RelayController.index", operationId: "AdminAPI.RelayController.index",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["admin:read"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
responses: %{ responses: %{
200 => 200 =>
@ -37,10 +37,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
def follow_operation do def follow_operation do
%Operation{ %Operation{
tags: ["Admin", "Relays"], tags: ["Relays"],
summary: "Follow a Relay", summary: "Follow a relay",
operationId: "AdminAPI.RelayController.follow", operationId: "AdminAPI.RelayController.follow",
security: [%{"oAuth" => ["write:follows"]}], security: [%{"oAuth" => ["admin:write:follows"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: request_body("Parameters", relay_url()), requestBody: request_body("Parameters", relay_url()),
responses: %{ responses: %{
@ -51,10 +51,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
def unfollow_operation do def unfollow_operation do
%Operation{ %Operation{
tags: ["Admin", "Relays"], tags: ["Relays"],
summary: "Unfollow a Relay", summary: "Unfollow a relay",
operationId: "AdminAPI.RelayController.unfollow", operationId: "AdminAPI.RelayController.unfollow",
security: [%{"oAuth" => ["write:follows"]}], security: [%{"oAuth" => ["admin:write:follows"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: request_body("Parameters", relay_unfollow()), requestBody: request_body("Parameters", relay_unfollow()),
responses: %{ responses: %{

View file

@ -19,10 +19,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Admin", "Reports"], tags: ["Report managment"],
summary: "Get a list of reports", summary: "Retrieve a list of reports",
operationId: "AdminAPI.ReportController.index", operationId: "AdminAPI.ReportController.index",
security: [%{"oAuth" => ["read:reports"]}], security: [%{"oAuth" => ["admin:read:reports"]}],
parameters: [ parameters: [
Operation.parameter( Operation.parameter(
:state, :state,
@ -69,11 +69,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Admin", "Reports"], tags: ["Report managment"],
summary: "Get an individual report", summary: "Retrieve a report",
operationId: "AdminAPI.ReportController.show", operationId: "AdminAPI.ReportController.show",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:reports"]}], security: [%{"oAuth" => ["admin:read:reports"]}],
responses: %{ responses: %{
200 => Operation.response("Report", "application/json", report()), 200 => Operation.response("Report", "application/json", report()),
404 => Operation.response("Not Found", "application/json", ApiError) 404 => Operation.response("Not Found", "application/json", ApiError)
@ -83,10 +83,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Admin", "Reports"], tags: ["Report managment"],
summary: "Change the state of one or multiple reports", summary: "Change state of specified reports",
operationId: "AdminAPI.ReportController.update", operationId: "AdminAPI.ReportController.update",
security: [%{"oAuth" => ["write:reports"]}], security: [%{"oAuth" => ["admin:write:reports"]}],
parameters: admin_api_params(), parameters: admin_api_params(),
requestBody: request_body("Parameters", update_request(), required: true), requestBody: request_body("Parameters", update_request(), required: true),
responses: %{ responses: %{
@ -99,8 +99,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def notes_create_operation do def notes_create_operation do
%Operation{ %Operation{
tags: ["Admin", "Reports"], tags: ["Report managment"],
summary: "Create report note", summary: "Add a note to the report",
operationId: "AdminAPI.ReportController.notes_create", operationId: "AdminAPI.ReportController.notes_create",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
requestBody: requestBody:
@ -110,7 +110,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
content: %Schema{type: :string, description: "The message"} content: %Schema{type: :string, description: "The message"}
} }
}), }),
security: [%{"oAuth" => ["write:reports"]}], security: [%{"oAuth" => ["admin:write:reports"]}],
responses: %{ responses: %{
204 => no_content_response(), 204 => no_content_response(),
404 => Operation.response("Not Found", "application/json", ApiError) 404 => Operation.response("Not Found", "application/json", ApiError)
@ -120,15 +120,15 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def notes_delete_operation do def notes_delete_operation do
%Operation{ %Operation{
tags: ["Admin", "Reports"], tags: ["Report managment"],
summary: "Delete report note", summary: "Delete note attached to the report",
operationId: "AdminAPI.ReportController.notes_delete", operationId: "AdminAPI.ReportController.notes_delete",
parameters: [ parameters: [
Operation.parameter(:report_id, :path, :string, "Report ID"), Operation.parameter(:report_id, :path, :string, "Report ID"),
Operation.parameter(:id, :path, :string, "Note ID") Operation.parameter(:id, :path, :string, "Note ID")
| admin_api_params() | admin_api_params()
], ],
security: [%{"oAuth" => ["write:reports"]}], security: [%{"oAuth" => ["admin:write:reports"]}],
responses: %{ responses: %{
204 => no_content_response(), 204 => no_content_response(),
404 => Operation.response("Not Found", "application/json", ApiError) 404 => Operation.response("Not Found", "application/json", ApiError)
@ -182,7 +182,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
properties: properties:
Map.merge(Account.schema().properties, %{ Map.merge(Account.schema().properties, %{
nickname: %Schema{type: :string}, nickname: %Schema{type: :string},
deactivated: %Schema{type: :boolean}, is_active: %Schema{type: :boolean},
local: %Schema{type: :boolean}, local: %Schema{type: :boolean},
roles: %Schema{ roles: %Schema{
type: :object, type: :object,

View file

@ -21,9 +21,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Admin", "Statuses"], tags: ["Status administration"],
operationId: "AdminAPI.StatusController.index", operationId: "AdminAPI.StatusController.index",
security: [%{"oAuth" => ["read:statuses"]}], summary: "Get all statuses",
security: [%{"oAuth" => ["admin:read:statuses"]}],
parameters: [ parameters: [
Operation.parameter( Operation.parameter(
:godmode, :godmode,
@ -69,11 +70,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Admin", "Statuses"], tags: ["Status adminitration)"],
summary: "Show Status", summary: "Get status",
operationId: "AdminAPI.StatusController.show", operationId: "AdminAPI.StatusController.show",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["admin:read:statuses"]}],
responses: %{ responses: %{
200 => Operation.response("Status", "application/json", status()), 200 => Operation.response("Status", "application/json", status()),
404 => Operation.response("Not Found", "application/json", ApiError) 404 => Operation.response("Not Found", "application/json", ApiError)
@ -83,11 +84,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Admin", "Statuses"], tags: ["Status adminitration)"],
summary: "Change the scope of an individual reported status", summary: "Change the scope of a status",
operationId: "AdminAPI.StatusController.update", operationId: "AdminAPI.StatusController.update",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["admin:write:statuses"]}],
requestBody: request_body("Parameters", update_request(), required: true), requestBody: request_body("Parameters", update_request(), required: true),
responses: %{ responses: %{
200 => Operation.response("Status", "application/json", Status), 200 => Operation.response("Status", "application/json", Status),
@ -98,11 +99,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Admin", "Statuses"], tags: ["Status adminitration)"],
summary: "Delete an individual reported status", summary: "Delete status",
operationId: "AdminAPI.StatusController.delete", operationId: "AdminAPI.StatusController.delete",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["admin:write:statuses"]}],
responses: %{ responses: %{
200 => empty_object_response(), 200 => empty_object_response(),
404 => Operation.response("Not Found", "application/json", ApiError) 404 => Operation.response("Not Found", "application/json", ApiError)
@ -132,7 +133,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
avatar: %Schema{type: :string}, avatar: %Schema{type: :string},
nickname: %Schema{type: :string}, nickname: %Schema{type: :string},
display_name: %Schema{type: :string}, display_name: %Schema{type: :string},
deactivated: %Schema{type: :boolean}, is_active: %Schema{type: :boolean},
local: %Schema{type: :boolean}, local: %Schema{type: :boolean},
roles: %Schema{ roles: %Schema{
type: :object, type: :object,

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do
@spec create_operation() :: Operation.t() @spec create_operation() :: Operation.t()
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["apps"], tags: ["Applications"],
summary: "Create an application", summary: "Create an application",
description: "Create a new application to obtain OAuth2 credentials", description: "Create a new application to obtain OAuth2 credentials",
operationId: "AppController.create", operationId: "AppController.create",
@ -45,8 +45,8 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do
def verify_credentials_operation do def verify_credentials_operation do
%Operation{ %Operation{
tags: ["apps"], tags: ["Applications"],
summary: "Verify your app works", summary: "Verify the application works",
description: "Confirm that the app's OAuth2 credentials work.", description: "Confirm that the app's OAuth2 credentials work.",
operationId: "AppController.verify_credentials", operationId: "AppController.verify_credentials",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["read"]}],

View file

@ -20,7 +20,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def mark_as_read_operation do def mark_as_read_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "Mark all messages in the chat as read", summary: "Mark all messages in the chat as read",
operationId: "ChatController.mark_as_read", operationId: "ChatController.mark_as_read",
parameters: [Operation.parameter(:id, :path, :string, "The ID of the Chat")], parameters: [Operation.parameter(:id, :path, :string, "The ID of the Chat")],
@ -43,8 +43,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def mark_message_as_read_operation do def mark_message_as_read_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "Mark one message in the chat as read", summary: "Mark a message as read",
operationId: "ChatController.mark_message_as_read", operationId: "ChatController.mark_message_as_read",
parameters: [ parameters: [
Operation.parameter(:id, :path, :string, "The ID of the Chat"), Operation.parameter(:id, :path, :string, "The ID of the Chat"),
@ -68,8 +68,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "Create a chat", summary: "Retrieve a chat",
operationId: "ChatController.show", operationId: "ChatController.show",
parameters: [ parameters: [
Operation.parameter( Operation.parameter(
@ -99,7 +99,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "Create a chat", summary: "Create a chat",
operationId: "ChatController.create", operationId: "ChatController.create",
parameters: [ parameters: [
@ -130,9 +130,31 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "Get a list of chats that you participated in", summary: "Retrieve list of chats (unpaginated)",
deprecated: true,
description:
"Deprecated due to no support for pagination. Using [/api/v2/pleroma/chats](#operation/ChatController.index2) instead is recommended.",
operationId: "ChatController.index", operationId: "ChatController.index",
parameters: [
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
],
responses: %{
200 => Operation.response("The chats of the user", "application/json", chats_response())
},
security: [
%{
"oAuth" => ["read:chats"]
}
]
}
end
def index2_operation do
%Operation{
tags: ["Chats"],
summary: "Retrieve list of chats",
operationId: "ChatController.index2",
parameters: [ parameters: [
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users") Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
| pagination_params() | pagination_params()
@ -150,8 +172,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def messages_operation do def messages_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "Get the most recent messages of the chat", summary: "Retrieve chat's messages",
operationId: "ChatController.messages", operationId: "ChatController.messages",
parameters: parameters:
[Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++ [Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++
@ -175,7 +197,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def post_chat_message_operation do def post_chat_message_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "Post a message to the chat", summary: "Post a message to the chat",
operationId: "ChatController.post_chat_message", operationId: "ChatController.post_chat_message",
parameters: [ parameters: [
@ -202,8 +224,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def delete_message_operation do def delete_message_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["Chats"],
summary: "delete_message", summary: "Delete message",
operationId: "ChatController.delete_message", operationId: "ChatController.delete_message",
parameters: [ parameters: [
Operation.parameter(:id, :path, :string, "The ID of the Chat"), Operation.parameter(:id, :path, :string, "The ID of the Chat"),

View file

@ -18,7 +18,7 @@ defmodule Pleroma.Web.ApiSpec.ConversationOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Conversations"], tags: ["Conversations"],
summary: "Show conversation", summary: "List of conversations",
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
operationId: "ConversationController.index", operationId: "ConversationController.index",
parameters: [ parameters: [
@ -44,18 +44,33 @@ defmodule Pleroma.Web.ApiSpec.ConversationOperation do
def mark_as_read_operation do def mark_as_read_operation do
%Operation{ %Operation{
tags: ["Conversations"], tags: ["Conversations"],
summary: "Mark as read", summary: "Mark conversation as read",
operationId: "ConversationController.mark_as_read", operationId: "ConversationController.mark_as_read",
parameters: [ parameters: [id_param()],
Operation.parameter(:id, :path, :string, "Conversation ID",
example: "123",
required: true
)
],
security: [%{"oAuth" => ["write:conversations"]}], security: [%{"oAuth" => ["write:conversations"]}],
responses: %{ responses: %{
200 => Operation.response("Conversation", "application/json", Conversation) 200 => Operation.response("Conversation", "application/json", Conversation)
} }
} }
end end
def delete_operation do
%Operation{
tags: ["Conversations"],
summary: "Remove conversation",
operationId: "ConversationController.delete",
parameters: [id_param()],
security: [%{"oAuth" => ["write:conversations"]}],
responses: %{
200 => empty_object_response()
}
}
end
def id_param do
Operation.parameter(:id, :path, :string, "Conversation ID",
example: "123",
required: true
)
end
end end

View file

@ -14,8 +14,8 @@ defmodule Pleroma.Web.ApiSpec.CustomEmojiOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["custom_emojis"], tags: ["Custom emojis"],
summary: "List custom custom emojis", summary: "Retrieve a list of custom emojis",
description: "Returns custom emojis that are available on the server.", description: "Returns custom emojis that are available on the server.",
operationId: "CustomEmojiController.index", operationId: "CustomEmojiController.index",
responses: %{ responses: %{

View file

@ -14,9 +14,8 @@ defmodule Pleroma.Web.ApiSpec.DomainBlockOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["domain_blocks"], tags: ["Domain blocks"],
summary: "Fetch domain blocks", summary: "Retrieve a list of blocked domains",
description: "View domains the user has blocked.",
security: [%{"oAuth" => ["follow", "read:blocks"]}], security: [%{"oAuth" => ["follow", "read:blocks"]}],
operationId: "DomainBlockController.index", operationId: "DomainBlockController.index",
responses: %{ responses: %{
@ -34,7 +33,7 @@ defmodule Pleroma.Web.ApiSpec.DomainBlockOperation do
# Supporting domain query parameter is deprecated in Mastodon API # Supporting domain query parameter is deprecated in Mastodon API
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["domain_blocks"], tags: ["Domain blocks"],
summary: "Block a domain", summary: "Block a domain",
description: """ description: """
Block a domain to: Block a domain to:
@ -55,7 +54,7 @@ defmodule Pleroma.Web.ApiSpec.DomainBlockOperation do
# Supporting domain query parameter is deprecated in Mastodon API # Supporting domain query parameter is deprecated in Mastodon API
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["domain_blocks"], tags: ["Domain blocks"],
summary: "Unblock a domain", summary: "Unblock a domain",
description: "Remove a domain block, if it exists in the user's array of blocked domains.", description: "Remove a domain block, if it exists in the user's array of blocked domains.",
operationId: "DomainBlockController.delete", operationId: "DomainBlockController.delete",

View file

@ -17,7 +17,7 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Emoji Reactions"], tags: ["Emoji reactions"],
summary: summary:
"Get an object of emoji to account mappings with accounts that reacted to the post", "Get an object of emoji to account mappings with accounts that reacted to the post",
parameters: [ parameters: [
@ -42,7 +42,7 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Emoji Reactions"], tags: ["Emoji reactions"],
summary: "React to a post with a unicode emoji", summary: "React to a post with a unicode emoji",
parameters: [ parameters: [
Operation.parameter(:id, :path, FlakeID, "Status ID", required: true), Operation.parameter(:id, :path, FlakeID, "Status ID", required: true),
@ -61,7 +61,7 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Emoji Reactions"], tags: ["Emoji reactions"],
summary: "Remove a reaction to a post with a unicode emoji", summary: "Remove a reaction to a post with a unicode emoji",
parameters: [ parameters: [
Operation.parameter(:id, :path, FlakeID, "Status ID", required: true), Operation.parameter(:id, :path, FlakeID, "Status ID", required: true),
@ -78,7 +78,7 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
end end
defp array_of_reactions_response do defp array_of_reactions_response do
Operation.response("Array of Emoji Reactions", "application/json", %Schema{ Operation.response("Array of Emoji reactions", "application/json", %Schema{
type: :array, type: :array,
items: emoji_reaction(), items: emoji_reaction(),
example: [emoji_reaction().example] example: [emoji_reaction().example]

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
alias OpenApiSpex.Operation alias OpenApiSpex.Operation
alias OpenApiSpex.Schema alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Helpers alias Pleroma.Web.ApiSpec.Helpers
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
def open_api_operation(action) do def open_api_operation(action) do
@ -15,57 +16,64 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["apps"], tags: ["Filters"],
summary: "View all filters", summary: "All filters",
operationId: "FilterController.index", operationId: "FilterController.index",
security: [%{"oAuth" => ["read:filters"]}], security: [%{"oAuth" => ["read:filters"]}],
responses: %{ responses: %{
200 => Operation.response("Filters", "application/json", array_of_filters()) 200 => Operation.response("Filters", "application/json", array_of_filters()),
403 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["apps"], tags: ["Filters"],
summary: "Create a filter", summary: "Create a filter",
operationId: "FilterController.create", operationId: "FilterController.create",
requestBody: Helpers.request_body("Parameters", create_request(), required: true), requestBody: Helpers.request_body("Parameters", create_request(), required: true),
security: [%{"oAuth" => ["write:filters"]}], security: [%{"oAuth" => ["write:filters"]}],
responses: %{200 => Operation.response("Filter", "application/json", filter())} responses: %{
200 => Operation.response("Filter", "application/json", filter()),
403 => Operation.response("Error", "application/json", ApiError)
}
} }
end end
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["apps"], tags: ["Filters"],
summary: "View all filters", summary: "Filter",
parameters: [id_param()], parameters: [id_param()],
operationId: "FilterController.show", operationId: "FilterController.show",
security: [%{"oAuth" => ["read:filters"]}], security: [%{"oAuth" => ["read:filters"]}],
responses: %{ responses: %{
200 => Operation.response("Filter", "application/json", filter()) 200 => Operation.response("Filter", "application/json", filter()),
403 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["apps"], tags: ["Filters"],
summary: "Update a filter", summary: "Update a filter",
parameters: [id_param()], parameters: [id_param()],
operationId: "FilterController.update", operationId: "FilterController.update",
requestBody: Helpers.request_body("Parameters", update_request(), required: true), requestBody: Helpers.request_body("Parameters", update_request(), required: true),
security: [%{"oAuth" => ["write:filters"]}], security: [%{"oAuth" => ["write:filters"]}],
responses: %{ responses: %{
200 => Operation.response("Filter", "application/json", filter()) 200 => Operation.response("Filter", "application/json", filter()),
403 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["apps"], tags: ["Filters"],
summary: "Remove a filter", summary: "Remove a filter",
parameters: [id_param()], parameters: [id_param()],
operationId: "FilterController.delete", operationId: "FilterController.delete",
@ -75,7 +83,8 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
Operation.response("Filter", "application/json", %Schema{ Operation.response("Filter", "application/json", %Schema{
type: :object, type: :object,
description: "Empty object" description: "Empty object"
}) }),
403 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end
@ -210,15 +219,13 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
nullable: true, nullable: true,
description: "Consider word boundaries?", description: "Consider word boundaries?",
default: true default: true
},
expires_in: %Schema{
nullable: true,
type: :integer,
description:
"Number of seconds from now the filter should expire. Otherwise, null for a filter that doesn't expire."
} }
# TODO: probably should implement filter expiration
# expires_in: %Schema{
# type: :string,
# format: :"date-time",
# description:
# "ISO 8601 Datetime for when the filter expires. Otherwise,
# null for a filter that doesn't expire."
# }
}, },
required: [:phrase, :context], required: [:phrase, :context],
example: %{ example: %{

View file

@ -15,8 +15,8 @@ defmodule Pleroma.Web.ApiSpec.FollowRequestOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Follow Requests"], tags: ["Follow requests"],
summary: "Pending Follows", summary: "Retrieve follow requests",
security: [%{"oAuth" => ["read:follows", "follow"]}], security: [%{"oAuth" => ["read:follows", "follow"]}],
operationId: "FollowRequestController.index", operationId: "FollowRequestController.index",
responses: %{ responses: %{
@ -32,8 +32,8 @@ defmodule Pleroma.Web.ApiSpec.FollowRequestOperation do
def authorize_operation do def authorize_operation do
%Operation{ %Operation{
tags: ["Follow Requests"], tags: ["Follow requests"],
summary: "Accept Follow", summary: "Accept follow request",
operationId: "FollowRequestController.authorize", operationId: "FollowRequestController.authorize",
parameters: [id_param()], parameters: [id_param()],
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -45,8 +45,8 @@ defmodule Pleroma.Web.ApiSpec.FollowRequestOperation do
def reject_operation do def reject_operation do
%Operation{ %Operation{
tags: ["Follow Requests"], tags: ["Follow requests"],
summary: "Reject Follow", summary: "Reject follow request",
operationId: "FollowRequestController.reject", operationId: "FollowRequestController.reject",
parameters: [id_param()], parameters: [id_param()],
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],

View file

@ -14,7 +14,7 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Instance"], tags: ["Instance"],
summary: "Fetch instance", summary: "Retrieve instance information",
description: "Information about the server", description: "Information about the server",
operationId: "InstanceController.show", operationId: "InstanceController.show",
responses: %{ responses: %{
@ -26,7 +26,7 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
def peers_operation do def peers_operation do
%Operation{ %Operation{
tags: ["Instance"], tags: ["Instance"],
summary: "List of known hosts", summary: "Retrieve list of known instances",
operationId: "InstanceController.peers", operationId: "InstanceController.peers",
responses: %{ responses: %{
200 => Operation.response("Array of domains", "application/json", array_of_domains()) 200 => Operation.response("Array of domains", "application/json", array_of_domains())

View file

@ -20,7 +20,7 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Lists"], tags: ["Lists"],
summary: "Show user's lists", summary: "Retrieve a list of lists",
description: "Fetch all lists that the user owns", description: "Fetch all lists that the user owns",
security: [%{"oAuth" => ["read:lists"]}], security: [%{"oAuth" => ["read:lists"]}],
operationId: "ListController.index", operationId: "ListController.index",
@ -49,7 +49,7 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Lists"], tags: ["Lists"],
summary: "Show a single list", summary: "Retrieve a list",
description: "Fetch the list with the given ID. Used for verifying the title of a list.", description: "Fetch the list with the given ID. Used for verifying the title of a list.",
operationId: "ListController.show", operationId: "ListController.show",
parameters: [id_param()], parameters: [id_param()],
@ -93,7 +93,7 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
def list_accounts_operation do def list_accounts_operation do
%Operation{ %Operation{
tags: ["Lists"], tags: ["Lists"],
summary: "View accounts in list", summary: "Retrieve accounts in list",
operationId: "ListController.list_accounts", operationId: "ListController.list_accounts",
parameters: [id_param()], parameters: [id_param()],
security: [%{"oAuth" => ["read:lists"]}], security: [%{"oAuth" => ["read:lists"]}],

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["media"], tags: ["Media attachments"],
summary: "Upload media as attachment", summary: "Upload media as attachment",
description: "Creates an attachment to be used with a new status.", description: "Creates an attachment to be used with a new status.",
operationId: "MediaController.create", operationId: "MediaController.create",
@ -56,8 +56,8 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["media"], tags: ["Media attachments"],
summary: "Upload media as attachment", summary: "Update attachment",
description: "Creates an attachment to be used with a new status.", description: "Creates an attachment to be used with a new status.",
operationId: "MediaController.update", operationId: "MediaController.update",
security: [%{"oAuth" => ["write:media"]}], security: [%{"oAuth" => ["write:media"]}],
@ -97,8 +97,8 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["media"], tags: ["Media attachments"],
summary: "Show Uploaded media attachment", summary: "Attachment",
operationId: "MediaController.show", operationId: "MediaController.show",
parameters: [id_param()], parameters: [id_param()],
security: [%{"oAuth" => ["read:media"]}], security: [%{"oAuth" => ["read:media"]}],
@ -112,8 +112,8 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do
def create2_operation do def create2_operation do
%Operation{ %Operation{
tags: ["media"], tags: ["Media attachments"],
summary: "Upload media as attachment", summary: "Upload media as attachment (v2)",
description: "Creates an attachment to be used with a new status.", description: "Creates an attachment to be used with a new status.",
operationId: "MediaController.create2", operationId: "MediaController.create2",
security: [%{"oAuth" => ["write:media"]}], security: [%{"oAuth" => ["write:media"]}],

View file

@ -22,7 +22,7 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Notifications"], tags: ["Notifications"],
summary: "Get all notifications", summary: "Retrieve a list of notifications",
description: description:
"Notifications concerning the user. This API returns Link headers containing links to the next/previous page. However, the links can also be constructed dynamically using query params and `id` values.", "Notifications concerning the user. This API returns Link headers containing links to the next/previous page. However, the links can also be constructed dynamically using query params and `id` values.",
operationId: "NotificationController.index", operationId: "NotificationController.index",
@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Notifications"], tags: ["Notifications"],
summary: "Get a single notification", summary: "Retrieve a notification",
description: "View information about a notification with a given ID.", description: "View information about a notification with a given ID.",
operationId: "NotificationController.show", operationId: "NotificationController.show",
security: [%{"oAuth" => ["read:notifications"]}], security: [%{"oAuth" => ["read:notifications"]}],
@ -99,7 +99,7 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
def dismiss_operation do def dismiss_operation do
%Operation{ %Operation{
tags: ["Notifications"], tags: ["Notifications"],
summary: "Dismiss a single notification", summary: "Dismiss a notification",
description: "Clear a single notification from the server.", description: "Clear a single notification from the server.",
operationId: "NotificationController.dismiss", operationId: "NotificationController.dismiss",
parameters: [id_param()], parameters: [id_param()],

View file

@ -18,8 +18,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
def confirmation_resend_operation do def confirmation_resend_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Account credentials"],
summary: "Resend confirmation email. Expects `email` or `nickname`", summary: "Resend confirmation email",
description: "Expects `email` or `nickname`.",
operationId: "PleromaAPI.AccountController.confirmation_resend", operationId: "PleromaAPI.AccountController.confirmation_resend",
parameters: [ parameters: [
Operation.parameter(:email, :query, :string, "Email of that needs to be verified", Operation.parameter(:email, :query, :string, "Email of that needs to be verified",
@ -41,8 +42,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
def favourites_operation do def favourites_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Retrieve account information"],
summary: "Returns favorites timeline of any user", summary: "Favorites",
description:
"Only returns data if the user has opted into sharing it. See `hide_favorites` in [Update account credentials](#operation/AccountController.update_credentials).",
operationId: "PleromaAPI.AccountController.favourites", operationId: "PleromaAPI.AccountController.favourites",
parameters: [id_param() | pagination_params()], parameters: [id_param() | pagination_params()],
security: [%{"oAuth" => ["read:favourites"]}], security: [%{"oAuth" => ["read:favourites"]}],
@ -61,8 +64,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
def subscribe_operation do def subscribe_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Account actions"],
summary: "Subscribe to receive notifications for all statuses posted by a user", summary: "Subscribe",
description: "Receive notifications for all statuses posted by the account.",
operationId: "PleromaAPI.AccountController.subscribe", operationId: "PleromaAPI.AccountController.subscribe",
parameters: [id_param()], parameters: [id_param()],
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -75,8 +79,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
def unsubscribe_operation do def unsubscribe_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Account actions"],
summary: "Unsubscribe to stop receiving notifications from user statuses", summary: "Unsubscribe",
description: "Stop receiving notifications for all statuses posted by the account.",
operationId: "PleromaAPI.AccountController.unsubscribe", operationId: "PleromaAPI.AccountController.unsubscribe",
parameters: [id_param()], parameters: [id_param()],
security: [%{"oAuth" => ["follow", "write:follows"]}], security: [%{"oAuth" => ["follow", "write:follows"]}],

View file

@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaConversationOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Conversations"], tags: ["Conversations"],
summary: "The conversation with the given ID", summary: "Conversation",
parameters: [ parameters: [
Operation.parameter(:id, :path, :string, "Conversation ID", Operation.parameter(:id, :path, :string, "Conversation ID",
example: "123", example: "123",
@ -37,7 +37,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaConversationOperation do
def statuses_operation do def statuses_operation do
%Operation{ %Operation{
tags: ["Conversations"], tags: ["Conversations"],
summary: "Timeline for a given conversation", summary: "Timeline for conversation",
parameters: [ parameters: [
Operation.parameter(:id, :path, :string, "Conversation ID", Operation.parameter(:id, :path, :string, "Conversation ID",
example: "123", example: "123",
@ -61,7 +61,8 @@ defmodule Pleroma.Web.ApiSpec.PleromaConversationOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Conversations"], tags: ["Conversations"],
summary: "Update a conversation. Used to change the set of recipients.", summary: "Update conversation",
description: "Change set of recipients for the conversation.",
parameters: [ parameters: [
Operation.parameter(:id, :path, :string, "Conversation ID", Operation.parameter(:id, :path, :string, "Conversation ID",
example: "123", example: "123",
@ -86,7 +87,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaConversationOperation do
def mark_as_read_operation do def mark_as_read_operation do
%Operation{ %Operation{
tags: ["Conversations"], tags: ["Conversations"],
summary: "Marks all user's conversations as read", summary: "Marks all conversations as read",
security: [%{"oAuth" => ["write:conversations"]}], security: [%{"oAuth" => ["write:conversations"]}],
operationId: "PleromaAPI.ConversationController.mark_as_read", operationId: "PleromaAPI.ConversationController.mark_as_read",
responses: %{ responses: %{

View file

@ -16,10 +16,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Add new file to the pack", summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.add_file", operationId: "PleromaAPI.EmojiPackController.add_file",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", create_request(), required: true), requestBody: request_body("Parameters", create_request(), required: true),
parameters: [name_param()], parameters: [name_param()],
responses: %{ responses: %{
@ -62,10 +62,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Add new file to the pack", summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.update_file", operationId: "PleromaAPI.EmojiPackController.update_file",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", update_request(), required: true), requestBody: request_body("Parameters", update_request(), required: true),
parameters: [name_param()], parameters: [name_param()],
responses: %{ responses: %{
@ -106,10 +106,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Delete emoji file from pack", summary: "Delete emoji file from pack",
operationId: "PleromaAPI.EmojiPackController.delete_file", operationId: "PleromaAPI.EmojiPackController.delete_file",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
parameters: [ parameters: [
name_param(), name_param(),
Operation.parameter(:shortcode, :query, :string, "File shortcode", Operation.parameter(:shortcode, :query, :string, "File shortcode",

View file

@ -16,9 +16,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def remote_operation do def remote_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Make request to another instance for emoji packs list", summary: "Make request to another instance for emoji packs list",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
parameters: [ parameters: [
url_param(), url_param(),
Operation.parameter( Operation.parameter(
@ -44,7 +44,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji packs"],
summary: "Lists local custom emoji packs", summary: "Lists local custom emoji packs",
operationId: "PleromaAPI.EmojiPackController.index", operationId: "PleromaAPI.EmojiPackController.index",
parameters: [ parameters: [
@ -69,7 +69,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji packs"],
summary: "Show emoji pack", summary: "Show emoji pack",
operationId: "PleromaAPI.EmojiPackController.show", operationId: "PleromaAPI.EmojiPackController.show",
parameters: [ parameters: [
@ -97,7 +97,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def archive_operation do def archive_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji packs"],
summary: "Requests a local pack archive from the instance", summary: "Requests a local pack archive from the instance",
operationId: "PleromaAPI.EmojiPackController.archive", operationId: "PleromaAPI.EmojiPackController.archive",
parameters: [name_param()], parameters: [name_param()],
@ -115,10 +115,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def download_operation do def download_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Download pack from another instance", summary: "Download pack from another instance",
operationId: "PleromaAPI.EmojiPackController.download", operationId: "PleromaAPI.EmojiPackController.download",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", download_request(), required: true), requestBody: request_body("Parameters", download_request(), required: true),
responses: %{ responses: %{
200 => ok_response(), 200 => ok_response(),
@ -145,10 +145,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Create an empty pack", summary: "Create an empty pack",
operationId: "PleromaAPI.EmojiPackController.create", operationId: "PleromaAPI.EmojiPackController.create",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
parameters: [name_param()], parameters: [name_param()],
responses: %{ responses: %{
200 => ok_response(), 200 => ok_response(),
@ -161,10 +161,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Delete a custom emoji pack", summary: "Delete a custom emoji pack",
operationId: "PleromaAPI.EmojiPackController.delete", operationId: "PleromaAPI.EmojiPackController.delete",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
parameters: [name_param()], parameters: [name_param()],
responses: %{ responses: %{
200 => ok_response(), 200 => ok_response(),
@ -177,10 +177,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Updates (replaces) pack metadata", summary: "Updates (replaces) pack metadata",
operationId: "PleromaAPI.EmojiPackController.update", operationId: "PleromaAPI.EmojiPackController.update",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", update_request(), required: true), requestBody: request_body("Parameters", update_request(), required: true),
parameters: [name_param()], parameters: [name_param()],
responses: %{ responses: %{
@ -193,10 +193,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def import_from_filesystem_operation do def import_from_filesystem_operation do
%Operation{ %Operation{
tags: ["Emoji Packs"], tags: ["Emoji pack administration"],
summary: "Imports packs from filesystem", summary: "Imports packs from filesystem",
operationId: "PleromaAPI.EmojiPackController.import", operationId: "PleromaAPI.EmojiPackController.import",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["admin:write"]}],
responses: %{ responses: %{
200 => 200 =>
Operation.response("Array of imported pack names", "application/json", %Schema{ Operation.response("Array of imported pack names", "application/json", %Schema{

View file

@ -13,8 +13,8 @@ defmodule Pleroma.Web.ApiSpec.PleromaInstancesOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["PleromaInstances"], tags: ["Instance"],
summary: "Instances federation status", summary: "Retrieve federation status",
description: "Information about instances deemed unreachable by the server", description: "Information about instances deemed unreachable by the server",
operationId: "PleromaInstances.show", operationId: "PleromaInstances.show",
responses: %{ responses: %{

View file

@ -17,7 +17,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaMascotOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Mascot"], tags: ["Mascot"],
summary: "Gets user mascot image", summary: "Retrieve mascot",
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
operationId: "PleromaAPI.MascotController.show", operationId: "PleromaAPI.MascotController.show",
responses: %{ responses: %{
@ -29,7 +29,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaMascotOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Mascot"], tags: ["Mascot"],
summary: "Set/clear user avatar image", summary: "Set or clear mascot",
description: description:
"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`.", "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`.",
operationId: "PleromaAPI.MascotController.update", operationId: "PleromaAPI.MascotController.update",

View file

@ -18,7 +18,8 @@ defmodule Pleroma.Web.ApiSpec.PleromaNotificationOperation do
def mark_as_read_operation do def mark_as_read_operation do
%Operation{ %Operation{
tags: ["Notifications"], tags: ["Notifications"],
summary: "Mark notifications as read. Query parameters are mutually exclusive.", summary: "Mark notifications as read",
description: "Query parameters are mutually exclusive.",
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
type: :object, type: :object,
@ -32,7 +33,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaNotificationOperation do
responses: %{ responses: %{
200 => 200 =>
Operation.response( Operation.response(
"A Notification or array of Motifications", "A Notification or array of Notifications",
"application/json", "application/json",
%Schema{ %Schema{
anyOf: [ anyOf: [

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["reports"], tags: ["Reports"],
summary: "File a report", summary: "File a report",
description: "Report problematic users to your moderators", description: "Report problematic users to your moderators",
operationId: "ReportController.create", operationId: "ReportController.create",

View file

@ -18,7 +18,7 @@ defmodule Pleroma.Web.ApiSpec.ScheduledActivityOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Scheduled Statuses"], tags: ["Scheduled statuses"],
summary: "View scheduled statuses", summary: "View scheduled statuses",
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
parameters: pagination_params(), parameters: pagination_params(),
@ -35,7 +35,7 @@ defmodule Pleroma.Web.ApiSpec.ScheduledActivityOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Scheduled Statuses"], tags: ["Scheduled statuses"],
summary: "View a single scheduled status", summary: "View a single scheduled status",
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
parameters: [id_param()], parameters: [id_param()],
@ -49,7 +49,7 @@ defmodule Pleroma.Web.ApiSpec.ScheduledActivityOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Scheduled Statuses"], tags: ["Scheduled statuses"],
summary: "Schedule a status", summary: "Schedule a status",
operationId: "ScheduledActivity.update", operationId: "ScheduledActivity.update",
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
@ -75,7 +75,7 @@ defmodule Pleroma.Web.ApiSpec.ScheduledActivityOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Scheduled Statuses"], tags: ["Scheduled statuses"],
summary: "Cancel a scheduled status", summary: "Cancel a scheduled status",
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
parameters: [id_param()], parameters: [id_param()],

View file

@ -22,8 +22,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Retrieve status information"],
summary: "Get multiple statuses by IDs", summary: "Multiple statuses",
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
parameters: [ parameters: [
Operation.parameter( Operation.parameter(
@ -48,7 +48,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Publish new status", summary: "Publish new status",
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
description: "Post a new status", description: "Post a new status",
@ -68,8 +68,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Retrieve status information"],
summary: "View specific status", summary: "Status",
description: "View information about a status", description: "View information about a status",
operationId: "StatusController.show", operationId: "StatusController.show",
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
@ -91,8 +91,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Delete status", summary: "Delete",
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
description: "Delete one of your own statuses", description: "Delete one of your own statuses",
operationId: "StatusController.delete", operationId: "StatusController.delete",
@ -107,8 +107,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def reblog_operation do def reblog_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Boost", summary: "Reblog",
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
description: "Share a status", description: "Share a status",
operationId: "StatusController.reblog", operationId: "StatusController.reblog",
@ -129,8 +129,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unreblog_operation do def unreblog_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Undo boost", summary: "Undo reblog",
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
description: "Undo a reshare of a status", description: "Undo a reshare of a status",
operationId: "StatusController.unreblog", operationId: "StatusController.unreblog",
@ -144,7 +144,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def favourite_operation do def favourite_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Favourite", summary: "Favourite",
security: [%{"oAuth" => ["write:favourites"]}], security: [%{"oAuth" => ["write:favourites"]}],
description: "Add a status to your favourites list", description: "Add a status to your favourites list",
@ -159,7 +159,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unfavourite_operation do def unfavourite_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Undo favourite", summary: "Undo favourite",
security: [%{"oAuth" => ["write:favourites"]}], security: [%{"oAuth" => ["write:favourites"]}],
description: "Remove a status from your favourites list", description: "Remove a status from your favourites list",
@ -174,7 +174,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def pin_operation do def pin_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Pin to profile", summary: "Pin to profile",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
description: "Feature one of your own public statuses at the top of your profile", description: "Feature one of your own public statuses at the top of your profile",
@ -189,8 +189,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unpin_operation do def unpin_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Unpin to profile", summary: "Unpin from profile",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
description: "Unfeature a status from the top of your profile", description: "Unfeature a status from the top of your profile",
operationId: "StatusController.unpin", operationId: "StatusController.unpin",
@ -204,7 +204,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def bookmark_operation do def bookmark_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Bookmark", summary: "Bookmark",
security: [%{"oAuth" => ["write:bookmarks"]}], security: [%{"oAuth" => ["write:bookmarks"]}],
description: "Privately bookmark a status", description: "Privately bookmark a status",
@ -218,7 +218,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unbookmark_operation do def unbookmark_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Undo bookmark", summary: "Undo bookmark",
security: [%{"oAuth" => ["write:bookmarks"]}], security: [%{"oAuth" => ["write:bookmarks"]}],
description: "Remove a status from your private bookmarks", description: "Remove a status from your private bookmarks",
@ -232,7 +232,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def mute_conversation_operation do def mute_conversation_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Mute conversation", summary: "Mute conversation",
security: [%{"oAuth" => ["write:mutes"]}], security: [%{"oAuth" => ["write:mutes"]}],
description: "Do not receive notifications for the thread that this status is part of.", description: "Do not receive notifications for the thread that this status is part of.",
@ -267,7 +267,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unmute_conversation_operation do def unmute_conversation_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Status actions"],
summary: "Unmute conversation", summary: "Unmute conversation",
security: [%{"oAuth" => ["write:mutes"]}], security: [%{"oAuth" => ["write:mutes"]}],
description: description:
@ -283,7 +283,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def card_operation do def card_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Retrieve status information"],
deprecated: true, deprecated: true,
summary: "Preview card", summary: "Preview card",
description: "Deprecated in favor of card property inlined on Status entity", description: "Deprecated in favor of card property inlined on Status entity",
@ -311,7 +311,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def favourited_by_operation do def favourited_by_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Retrieve status information"],
summary: "Favourited by", summary: "Favourited by",
description: "View who favourited a given status", description: "View who favourited a given status",
operationId: "StatusController.favourited_by", operationId: "StatusController.favourited_by",
@ -331,9 +331,9 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def reblogged_by_operation do def reblogged_by_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Retrieve status information"],
summary: "Boosted by", summary: "Reblogged by",
description: "View who boosted a given status", description: "View who reblogged a given status",
operationId: "StatusController.reblogged_by", operationId: "StatusController.reblogged_by",
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
parameters: [id_param()], parameters: [id_param()],
@ -351,7 +351,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def context_operation do def context_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Retrieve status information"],
summary: "Parent and child statuses", summary: "Parent and child statuses",
description: "View statuses above and below this status in the thread", description: "View statuses above and below this status in the thread",
operationId: "StatusController.context", operationId: "StatusController.context",
@ -365,7 +365,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def favourites_operation do def favourites_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Timelines"],
summary: "Favourited statuses", summary: "Favourited statuses",
description: description:
"Statuses the user has favourited. Please note that you have to use the link headers to paginate this. You can not build the query parameters yourself.", "Statuses the user has favourited. Please note that you have to use the link headers to paginate this. You can not build the query parameters yourself.",
@ -380,7 +380,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def bookmarks_operation do def bookmarks_operation do
%Operation{ %Operation{
tags: ["Statuses"], tags: ["Timelines"],
summary: "Bookmarked statuses", summary: "Bookmarked statuses",
description: "Statuses the user has bookmarked", description: "Statuses the user has bookmarked",
operationId: "StatusController.bookmarks", operationId: "StatusController.bookmarks",
@ -413,34 +413,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
items: %Schema{type: :string}, items: %Schema{type: :string},
description: "Array of Attachment ids to be attached as media." description: "Array of Attachment ids to be attached as media."
}, },
poll: %Schema{ poll: poll_params(),
nullable: true,
type: :object,
required: [:options],
properties: %{
options: %Schema{
type: :array,
items: %Schema{type: :string},
description: "Array of possible answers. Must be provided with `poll[expires_in]`."
},
expires_in: %Schema{
type: :integer,
nullable: true,
description:
"Duration the poll should be open, in seconds. Must be provided with `poll[options]`"
},
multiple: %Schema{
allOf: [BooleanLike],
nullable: true,
description: "Allow multiple choices?"
},
hide_totals: %Schema{
allOf: [BooleanLike],
nullable: true,
description: "Hide vote counts until the poll ends?"
}
}
},
in_reply_to_id: %Schema{ in_reply_to_id: %Schema{
nullable: true, nullable: true,
allOf: [FlakeID], allOf: [FlakeID],
@ -522,6 +495,37 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
} }
end end
def poll_params do
%Schema{
nullable: true,
type: :object,
required: [:options, :expires_in],
properties: %{
options: %Schema{
type: :array,
items: %Schema{type: :string},
description: "Array of possible answers. Must be provided with `poll[expires_in]`."
},
expires_in: %Schema{
type: :integer,
nullable: true,
description:
"Duration the poll should be open, in seconds. Must be provided with `poll[options]`"
},
multiple: %Schema{
allOf: [BooleanLike],
nullable: true,
description: "Allow multiple choices?"
},
hide_totals: %Schema{
allOf: [BooleanLike],
nullable: true,
description: "Hide vote counts until the poll ends?"
}
}
}
end
def id_param do def id_param do
Operation.parameter(:id, :path, FlakeID, "Status ID", Operation.parameter(:id, :path, FlakeID, "Status ID",
example: "9umDrYheeY451cQnEe", example: "9umDrYheeY451cQnEe",

View file

@ -17,7 +17,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Push Subscriptions"], tags: ["Push subscriptions"],
summary: "Subscribe to push notifications", summary: "Subscribe to push notifications",
description: description:
"Add a Web Push API subscription to receive notifications. Each access token can have one push subscription. If you create a new subscription, the old subscription is deleted.", "Add a Web Push API subscription to receive notifications. Each access token can have one push subscription. If you create a new subscription, the old subscription is deleted.",
@ -25,7 +25,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
security: [%{"oAuth" => ["push"]}], security: [%{"oAuth" => ["push"]}],
requestBody: Helpers.request_body("Parameters", create_request(), required: true), requestBody: Helpers.request_body("Parameters", create_request(), required: true),
responses: %{ responses: %{
200 => Operation.response("Push Subscription", "application/json", PushSubscription), 200 => Operation.response("Push subscription", "application/json", PushSubscription),
400 => Operation.response("Error", "application/json", ApiError), 400 => Operation.response("Error", "application/json", ApiError),
403 => Operation.response("Error", "application/json", ApiError) 403 => Operation.response("Error", "application/json", ApiError)
} }
@ -34,13 +34,13 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Push Subscriptions"], tags: ["Push subscriptions"],
summary: "Get current subscription", summary: "Get current subscription",
description: "View the PushSubscription currently associated with this access token.", description: "View the PushSubscription currently associated with this access token.",
operationId: "SubscriptionController.show", operationId: "SubscriptionController.show",
security: [%{"oAuth" => ["push"]}], security: [%{"oAuth" => ["push"]}],
responses: %{ responses: %{
200 => Operation.response("Push Subscription", "application/json", PushSubscription), 200 => Operation.response("Push subscription", "application/json", PushSubscription),
403 => Operation.response("Error", "application/json", ApiError), 403 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError) 404 => Operation.response("Error", "application/json", ApiError)
} }
@ -49,7 +49,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Push Subscriptions"], tags: ["Push subscriptions"],
summary: "Change types of notifications", summary: "Change types of notifications",
description: description:
"Updates the current push subscription. Only the data part can be updated. To change fundamentals, a new subscription must be created instead.", "Updates the current push subscription. Only the data part can be updated. To change fundamentals, a new subscription must be created instead.",
@ -57,7 +57,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
security: [%{"oAuth" => ["push"]}], security: [%{"oAuth" => ["push"]}],
requestBody: Helpers.request_body("Parameters", update_request(), required: true), requestBody: Helpers.request_body("Parameters", update_request(), required: true),
responses: %{ responses: %{
200 => Operation.response("Push Subscription", "application/json", PushSubscription), 200 => Operation.response("Push subscription", "application/json", PushSubscription),
403 => Operation.response("Error", "application/json", ApiError) 403 => Operation.response("Error", "application/json", ApiError)
} }
} }
@ -65,7 +65,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Push Subscriptions"], tags: ["Push subscriptions"],
summary: "Remove current subscription", summary: "Remove current subscription",
description: "Removes the current Web Push API subscription.", description: "Removes the current Web Push API subscription.",
operationId: "SubscriptionController.delete", operationId: "SubscriptionController.delete",

View file

@ -25,6 +25,8 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
parameters: [ parameters: [
local_param(), local_param(),
remote_param(),
only_media_param(),
with_muted_param(), with_muted_param(),
exclude_visibilities_param(), exclude_visibilities_param(),
reply_visibility_param() | pagination_params() reply_visibility_param() | pagination_params()
@ -41,8 +43,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
tags: ["Timelines"], tags: ["Timelines"],
summary: "Direct timeline", summary: "Direct timeline",
description: description:
"View statuses with a “direct” privacy, from your account or in your notifications", "View statuses with a “direct” scope addressed to the account. Using this endpoint is discouraged, please use [conversations](#tag/Conversations) or [chats](#tag/Chats).",
deprecated: true,
parameters: [with_muted_param() | pagination_params()], parameters: [with_muted_param() | pagination_params()],
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
operationId: "TimelineController.direct", operationId: "TimelineController.direct",
@ -61,6 +62,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
local_param(), local_param(),
instance_param(), instance_param(),
only_media_param(), only_media_param(),
remote_param(),
with_muted_param(), with_muted_param(),
exclude_visibilities_param(), exclude_visibilities_param(),
reply_visibility_param() | pagination_params() reply_visibility_param() | pagination_params()
@ -107,6 +109,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
), ),
local_param(), local_param(),
only_media_param(), only_media_param(),
remote_param(),
with_muted_param(), with_muted_param(),
exclude_visibilities_param() | pagination_params() exclude_visibilities_param() | pagination_params()
], ],
@ -132,6 +135,9 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
required: true required: true
), ),
with_muted_param(), with_muted_param(),
local_param(),
remote_param(),
only_media_param(),
exclude_visibilities_param() | pagination_params() exclude_visibilities_param() | pagination_params()
], ],
operationId: "TimelineController.list", operationId: "TimelineController.list",
@ -198,4 +204,13 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
"Show only statuses with media attached?" "Show only statuses with media attached?"
) )
end end
defp remote_param do
Operation.parameter(
:remote,
:query,
%Schema{allOf: [BooleanLike], default: false},
"Show only remote statuses?"
)
end
end end

View file

@ -17,8 +17,8 @@ defmodule Pleroma.Web.ApiSpec.UserImportOperation do
def follow_operation do def follow_operation do
%Operation{ %Operation{
tags: ["follow_import"], tags: ["Data import"],
summary: "Imports your follows.", summary: "Import follows",
operationId: "UserImportController.follow", operationId: "UserImportController.follow",
requestBody: request_body("Parameters", import_request(), required: true), requestBody: request_body("Parameters", import_request(), required: true),
responses: %{ responses: %{
@ -31,8 +31,8 @@ defmodule Pleroma.Web.ApiSpec.UserImportOperation do
def blocks_operation do def blocks_operation do
%Operation{ %Operation{
tags: ["blocks_import"], tags: ["Data import"],
summary: "Imports your blocks.", summary: "Import blocks",
operationId: "UserImportController.blocks", operationId: "UserImportController.blocks",
requestBody: request_body("Parameters", import_request(), required: true), requestBody: request_body("Parameters", import_request(), required: true),
responses: %{ responses: %{
@ -45,8 +45,8 @@ defmodule Pleroma.Web.ApiSpec.UserImportOperation do
def mutes_operation do def mutes_operation do
%Operation{ %Operation{
tags: ["mutes_import"], tags: ["Data import"],
summary: "Imports your mutes.", summary: "Import mutes",
operationId: "UserImportController.mutes", operationId: "UserImportController.mutes",
requestBody: request_body("Parameters", import_request(), required: true), requestBody: request_body("Parameters", import_request(), required: true),
responses: %{ responses: %{

View file

@ -96,7 +96,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
hide_notification_contents: %Schema{type: :boolean} hide_notification_contents: %Schema{type: :boolean}
} }
}, },
relationship: AccountRelationship, relationship: %Schema{allOf: [AccountRelationship], nullable: true},
settings_store: %Schema{ settings_store: %Schema{
type: :object, type: :object,
description: description:

View file

@ -10,7 +10,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.AccountRelationship do
OpenApiSpex.schema(%{ OpenApiSpex.schema(%{
title: "AccountRelationship", title: "AccountRelationship",
description: "Response schema for relationship", description: "Relationship between current account and requested account",
type: :object, type: :object,
properties: %{ properties: %{
blocked_by: %Schema{type: :boolean}, blocked_by: %Schema{type: :boolean},

View file

@ -52,7 +52,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ChatMessage do
title: %Schema{type: :string, description: "Title of linked resource"}, title: %Schema{type: :string, description: "Title of linked resource"},
description: %Schema{type: :string, description: "Description of preview"} description: %Schema{type: :string, description: "Description of preview"}
} }
} },
unread: %Schema{type: :boolean, description: "Whether a message has been marked as read."}
}, },
example: %{ example: %{
"account_id" => "someflakeid", "account_id" => "someflakeid",
@ -69,7 +70,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ChatMessage do
} }
], ],
"id" => "14", "id" => "14",
"attachment" => nil "attachment" => nil,
"unread" => false
} }
}) })
end end

View file

@ -5,8 +5,8 @@
defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
alias OpenApiSpex.Schema alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.Attachment alias Pleroma.Web.ApiSpec.Schemas.Attachment
alias Pleroma.Web.ApiSpec.Schemas.Poll
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
alias Pleroma.Web.ApiSpec.StatusOperation
require OpenApiSpex require OpenApiSpex
@ -29,7 +29,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
spoiler_text: %Schema{type: :string, nullable: true}, spoiler_text: %Schema{type: :string, nullable: true},
visibility: %Schema{allOf: [VisibilityScope], nullable: true}, visibility: %Schema{allOf: [VisibilityScope], nullable: true},
scheduled_at: %Schema{type: :string, format: :"date-time", nullable: true}, scheduled_at: %Schema{type: :string, format: :"date-time", nullable: true},
poll: %Schema{allOf: [Poll], nullable: true}, poll: StatusOperation.poll_params(),
in_reply_to_id: %Schema{type: :string, nullable: true} in_reply_to_id: %Schema{type: :string, nullable: true}
} }
} }

View file

@ -23,6 +23,18 @@ defmodule Pleroma.Web.Endpoint do
# InstanceStatic needs to be before Plug.Static to be able to override shipped-static files # InstanceStatic needs to be before Plug.Static to be able to override shipped-static files
# If you're adding new paths to `only:` you'll need to configure them in InstanceStatic as well # If you're adding new paths to `only:` you'll need to configure them in InstanceStatic as well
# Cache-control headers are duplicated in case we turn off etags in the future # Cache-control headers are duplicated in case we turn off etags in the future
plug(
Pleroma.Web.Plugs.InstanceStatic,
at: "/",
from: :pleroma,
only: ["emoji", "images"],
gzip: true,
cache_control_for_etags: "public, max-age=1209600",
headers: %{
"cache-control" => "public, max-age=1209600"
}
)
plug(Pleroma.Web.Plugs.InstanceStatic, plug(Pleroma.Web.Plugs.InstanceStatic,
at: "/", at: "/",
gzip: true, gzip: true,

Some files were not shown because too many files have changed in this diff Show more