Merge branch 'develop' into 'fix/2412-filters'

# Conflicts:
#   CHANGELOG.md
This commit is contained in:
feld 2021-02-03 14:23:23 +00:00
commit 008499f65a
245 changed files with 1917 additions and 905 deletions

View file

@ -34,6 +34,14 @@ build:
- mix deps.get
- mix compile --force
spec-build:
stage: test
artifacts:
paths:
- spec.json
script:
- mix pleroma.openapi_spec spec.json
benchmark:
stage: benchmark
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
- 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:
image: alpine:3.9
stage: deploy

View file

@ -10,17 +10,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
- **Breaking**: Changed `mix pleroma.user toggle_activated` to `mix pleroma.user activate/deactivate`
- **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`
- 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.
- 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.
- 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.
- 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.
<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
</details>
### Added
@ -38,7 +47,7 @@ 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.
- Ability to set ActivityPub aliases for follower migration.
- Configurable background job limits for RichMedia (link previews) and MediaProxyWarmingPolicy
- Ability to define custom HTTP headers per each frontend
<details>
<summary>API Changes</summary>
@ -48,7 +57,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- 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.
- 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.
</details>
### Fixed
@ -58,12 +70,17 @@ 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.
- 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
- 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>
<summary>API Changes</summary>
- 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: 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>

View file

@ -726,7 +726,10 @@ config :pleroma, :frontends,
"git" => "https://git.pleroma.social/pleroma/fedi-fe",
"build_url" =>
"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" => %{
"name" => "admin-fe",

View file

@ -60,6 +60,12 @@ frontend_options = [
label: "Build directory",
type: :string,
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"
}
]
@ -3218,6 +3224,12 @@ config :pleroma, :config_description, [
type: :string,
description: "S3 host",
suggestions: ["s3.eu-central-1.amazonaws.com"]
},
%{
key: :region,
type: :string,
description: "S3 region (for AWS)",
suggestions: ["us-east-1"]
}
]
},

View file

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

View file

@ -893,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
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 allows sign in / sign up via external OAuth providers (e.g. Twitter, Facebook, Google, Microsoft, etc.).
@ -965,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
### :uri_schemes

View file

@ -287,7 +287,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)
- Response:
- 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`
@ -300,7 +311,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)
- Response:
- 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`

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).
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
- `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/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:
- `ap_id`: nullable URL string, ActivityPub id of the user

View file

@ -242,6 +242,13 @@ defmodule Mix.Tasks.Pleroma.Instance do
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}.")
File.write(config_path, result_config)
@ -275,10 +282,6 @@ defmodule Mix.Tasks.Pleroma.Instance do
indexable: indexable
)
unless File.exists?(static_dir) do
File.mkdir_p!(static_dir)
end
robots_txt_path = Path.join(static_dir, "robots.txt")
if File.exists?(robots_txt_path) do

View file

@ -0,0 +1,6 @@
defmodule Mix.Tasks.Pleroma.OpenapiSpec do
def run([path]) do
spec = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
File.write(path, spec)
end
end

View file

@ -113,11 +113,15 @@ defmodule Pleroma.List do
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])})
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)})
end

View file

@ -146,6 +146,7 @@ defmodule Pleroma.User do
field(:inbox, :string)
field(:shared_inbox, :string)
field(:accepts_chat_messages, :boolean, default: nil)
field(:last_active_at, :naive_datetime)
embeds_one(
:notification_settings,
@ -2030,6 +2031,15 @@ defmodule Pleroma.User do
|> hd()
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),
do: String.trim_leading(nickname_or_mention, "@")
@ -2444,4 +2454,19 @@ defmodule Pleroma.User do
def get_host(%User{ap_id: ap_id} = _user) do
URI.parse(ap_id).host
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

View file

@ -591,7 +591,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Enum.reverse()
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
|> Map.put(:type, ["Create", "Announce"])
@ -616,10 +630,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
}
|> user_activities_recipients()
|> 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
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"])
%{
@ -628,7 +652,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
}
|> user_activities_recipients()
|> fetch_activities(params, :offset)
|> Enum.reverse()
end
defp user_activities_recipients(%{godmode: true}), do: []
@ -735,6 +758,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
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
from(activity in query, where: activity.actor == ^actor_id)
end
@ -1111,6 +1140,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> restrict_tag_all(opts)
|> restrict_since(opts)
|> restrict_local(opts)
|> restrict_remote(opts)
|> restrict_actor(opts)
|> restrict_type(opts)
|> restrict_state(opts)

View file

@ -85,17 +85,18 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
{page, page_size} = page_params(params)
activities =
result =
ActivityPub.fetch_statuses(nil, %{
instance: instance,
limit: page_size,
offset: (page - 1) * page_size,
exclude_reblogs: not with_reblogs
exclude_reblogs: not with_reblogs,
total: true
})
conn
|> put_view(AdminAPI.StatusView)
|> render("index.json", %{activities: activities, as: :activity})
|> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
end
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
{page, page_size} = page_params(params)
activities =
result =
ActivityPub.fetch_user_activities(user, nil, %{
limit: page_size,
offset: (page - 1) * page_size,
godmode: godmode,
exclude_reblogs: not with_reblogs,
pagination_type: :offset
pagination_type: :offset,
total: true
})
conn
|> put_view(AdminAPI.StatusView)
|> render("index.json", %{activities: activities, as: :activity})
|> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
else
_ -> {:error, :not_found}
end

View file

@ -13,6 +13,10 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
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
safe_render_many(opts.activities, __MODULE__, "show.json", opts)
end

View file

@ -11,10 +11,10 @@ defmodule Pleroma.Web.ApiSpec do
@behaviour OpenApi
@impl OpenApi
def spec do
def spec(opts \\ []) do
%OpenApi{
servers:
if Phoenix.Endpoint.server?(:pleroma, Endpoint) do
if opts[:server_specific] do
[
# Populate the Server info from a phoenix endpoint
OpenApiSpex.Server.from_endpoint(Endpoint)
@ -23,9 +23,25 @@ defmodule Pleroma.Web.ApiSpec do
[]
end,
info: %OpenApiSpex.Info{
title: "Pleroma",
description: Application.spec(:pleroma, :description) |> to_string(),
version: Application.spec(:pleroma, :vsn) |> to_string()
title: "Pleroma API",
description: """
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!
""",
version: Application.spec(:pleroma, :vsn) |> to_string(),
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
paths: OpenApiSpex.Paths.from_router(Router),
@ -45,15 +61,73 @@ defmodule Pleroma.Web.ApiSpec do
authorizationUrl: "/oauth/authorize",
tokenUrl: "/oauth/token",
scopes: %{
"read" => "read",
"write" => "write",
"follow" => "follow",
"push" => "push"
# TODO: Document granular scopes
"read" => "Read everything",
"write" => "Write everything",
"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 packs",
"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" => ["Reports", "Suggestions"]}
]
}
}
# discover request/response schemas from path specs

View file

@ -26,7 +26,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
@spec create_operation() :: Operation.t()
def create_operation do
%Operation{
tags: ["accounts"],
tags: ["Account credentials"],
summary: "Register an account",
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.",
@ -43,7 +43,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def verify_credentials_operation do
%Operation{
tags: ["accounts"],
tags: ["Account credentials"],
description: "Test to make sure that the user token works.",
summary: "Verify account credentials",
operationId: "AccountController.verify_credentials",
@ -56,7 +56,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def update_credentials_operation do
%Operation{
tags: ["accounts"],
tags: ["Account credentials"],
summary: "Update account credentials",
description: "Update the user's display and preferences.",
operationId: "AccountController.update_credentials",
@ -71,8 +71,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def relationships_operation do
%Operation{
tags: ["accounts"],
summary: "Check relationships to other accounts",
tags: ["Retrieve account information"],
summary: "Relationship with current account",
operationId: "AccountController.relationships",
description: "Find out whether a given account is followed, blocked, muted, etc.",
security: [%{"oAuth" => ["read:follows"]}],
@ -95,11 +95,14 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def show_operation do
%Operation{
tags: ["accounts"],
tags: ["Retrieve account information"],
summary: "Account",
operationId: "AccountController.show",
description: "View information about a profile.",
parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
parameters: [
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
with_relationships_param()
],
responses: %{
200 => Operation.response("Account", "application/json", Account),
401 => Operation.response("Error", "application/json", ApiError),
@ -110,8 +113,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def statuses_operation do
%Operation{
tags: ["accounts"],
summary: "Statuses",
tags: ["Retrieve account information"],
operationId: "AccountController.statuses",
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)",
@ -130,7 +133,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:with_muted,
:query,
BooleanLike,
"Include statuses from muted acccounts."
"Include statuses from muted accounts."
),
Operation.parameter(:exclude_reblogs, :query, BooleanLike, "Exclude reblogs"),
Operation.parameter(:exclude_replies, :query, BooleanLike, "Exclude replies"),
@ -144,7 +147,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:with_muted,
:query,
BooleanLike,
"Include reactions from muted acccounts."
"Include reactions from muted accounts."
)
] ++ pagination_params(),
responses: %{
@ -157,7 +160,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def followers_operation do
%Operation{
tags: ["accounts"],
tags: ["Retrieve account information"],
summary: "Followers",
operationId: "AccountController.followers",
security: [%{"oAuth" => ["read:accounts"]}],
@ -176,7 +179,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def following_operation do
%Operation{
tags: ["accounts"],
tags: ["Retrieve account information"],
summary: "Following",
operationId: "AccountController.following",
security: [%{"oAuth" => ["read:accounts"]}],
@ -193,7 +196,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def lists_operation do
%Operation{
tags: ["accounts"],
tags: ["Retrieve account information"],
summary: "Lists containing this account",
operationId: "AccountController.lists",
security: [%{"oAuth" => ["read:lists"]}],
@ -205,7 +208,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def follow_operation do
%Operation{
tags: ["accounts"],
tags: ["Account actions"],
summary: "Follow",
operationId: "AccountController.follow",
security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -238,7 +241,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def unfollow_operation do
%Operation{
tags: ["accounts"],
tags: ["Account actions"],
summary: "Unfollow",
operationId: "AccountController.unfollow",
security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -254,7 +257,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def mute_operation do
%Operation{
tags: ["accounts"],
tags: ["Account actions"],
summary: "Mute",
operationId: "AccountController.mute",
security: [%{"oAuth" => ["follow", "write:mutes"]}],
@ -284,7 +287,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def unmute_operation do
%Operation{
tags: ["accounts"],
tags: ["Account actions"],
summary: "Unmute",
operationId: "AccountController.unmute",
security: [%{"oAuth" => ["follow", "write:mutes"]}],
@ -298,7 +301,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def block_operation do
%Operation{
tags: ["accounts"],
tags: ["Account actions"],
summary: "Block",
operationId: "AccountController.block",
security: [%{"oAuth" => ["follow", "write:blocks"]}],
@ -313,7 +316,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def unblock_operation do
%Operation{
tags: ["accounts"],
tags: ["Account actions"],
summary: "Unblock",
operationId: "AccountController.unblock",
security: [%{"oAuth" => ["follow", "write:blocks"]}],
@ -327,7 +330,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def follow_by_uri_operation do
%Operation{
tags: ["accounts"],
tags: ["Account actions"],
summary: "Follow by URI",
operationId: "AccountController.follows",
security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -342,12 +345,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def mutes_operation do
%Operation{
tags: ["accounts"],
summary: "Muted accounts",
tags: ["Blocks and mutes"],
summary: "Retrieve list of mutes",
operationId: "AccountController.mutes",
description: "Accounts the user has muted.",
security: [%{"oAuth" => ["follow", "read:mutes"]}],
parameters: pagination_params(),
parameters: [with_relationships_param() | pagination_params()],
responses: %{
200 => Operation.response("Accounts", "application/json", array_of_accounts())
}
@ -356,8 +359,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def blocks_operation do
%Operation{
tags: ["accounts"],
summary: "Blocked users",
tags: ["Blocks and mutes"],
summary: "Retrieve list of blocks",
operationId: "AccountController.blocks",
description: "View your blocks. See also accounts/:id/{block,unblock}",
security: [%{"oAuth" => ["read:blocks"]}],
@ -370,7 +373,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def endorsements_operation do
%Operation{
tags: ["accounts"],
tags: ["Retrieve account information"],
summary: "Endorsements",
operationId: "AccountController.endorsements",
description: "Not implemented",
@ -383,7 +386,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
def identity_proofs_operation do
%Operation{
tags: ["accounts"],
tags: ["Retrieve account information"],
summary: "Identity proofs",
operationId: "AccountController.identity_proofs",
# 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
%Operation{
tags: ["admin", "chat"],
tags: ["Chat administration"],
summary: "Delete an individual chat message",
operationId: "AdminAPI.ChatController.delete_message",
parameters: [
@ -41,8 +41,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
def messages_operation do
%Operation{
tags: ["admin", "chat"],
summary: "Get the most recent messages of the chat",
tags: ["Chat administration"],
summary: "Get chat's messages",
operationId: "AdminAPI.ChatController.messages",
parameters:
[Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++
@ -65,7 +65,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
def show_operation do
%Operation{
tags: ["chat"],
tags: ["Chat administration"],
summary: "Create a chat",
operationId: "AdminAPI.ChatController.show",
parameters: [

View file

@ -16,8 +16,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
def show_operation do
%Operation{
tags: ["Admin", "Config"],
summary: "Get list of merged default settings with saved in database",
tags: ["Instance configuration"],
summary: "Retrieve instance configuration",
operationId: "AdminAPI.ConfigController.show",
parameters: [
Operation.parameter(
@ -38,8 +38,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
def update_operation do
%Operation{
tags: ["Admin", "Config"],
summary: "Update config settings",
tags: ["Instance configuration"],
summary: "Update instance configuration",
operationId: "AdminAPI.ConfigController.update",
security: [%{"oAuth" => ["write"]}],
parameters: admin_api_params(),
@ -71,8 +71,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
def descriptions_operation do
%Operation{
tags: ["Admin", "Config"],
summary: "Get JSON with config descriptions.",
tags: ["Instance configuration"],
summary: "Retrieve config description",
operationId: "AdminAPI.ConfigController.descriptions",
security: [%{"oAuth" => ["read"]}],
parameters: admin_api_params(),

View file

@ -16,8 +16,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.FrontendOperation do
def index_operation do
%Operation{
tags: ["Admin", "Reports"],
summary: "Get a list of available frontends",
tags: ["Frontend managment"],
summary: "Retrieve a list of available frontends",
operationId: "AdminAPI.FrontendController.index",
security: [%{"oAuth" => ["read"]}],
responses: %{
@ -29,7 +29,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.FrontendOperation do
def install_operation do
%Operation{
tags: ["Admin", "Reports"],
tags: ["Frontend managment"],
summary: "Install a frontend",
operationId: "AdminAPI.FrontendController.install",
security: [%{"oAuth" => ["read"]}],

View file

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

View file

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

View file

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

View file

@ -16,8 +16,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def index_operation do
%Operation{
summary: "List OAuth apps",
tags: ["Admin", "oAuth Apps"],
summary: "Retrieve a list of OAuth applications",
tags: ["OAuth application managment"],
operationId: "AdminAPI.OAuthAppController.index",
security: [%{"oAuth" => ["write"]}],
parameters: [
@ -69,8 +69,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def create_operation do
%Operation{
tags: ["Admin", "oAuth Apps"],
summary: "Create OAuth App",
tags: ["OAuth application managment"],
summary: "Create an OAuth application",
operationId: "AdminAPI.OAuthAppController.create",
requestBody: request_body("Parameters", create_request()),
parameters: admin_api_params(),
@ -84,8 +84,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def update_operation do
%Operation{
tags: ["Admin", "oAuth Apps"],
summary: "Update OAuth App",
tags: ["OAuth application managment"],
summary: "Update OAuth application",
operationId: "AdminAPI.OAuthAppController.update",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}],
@ -102,8 +102,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
def delete_operation do
%Operation{
tags: ["Admin", "oAuth Apps"],
summary: "Delete OAuth App",
tags: ["OAuth application managment"],
summary: "Delete OAuth application",
operationId: "AdminAPI.OAuthAppController.delete",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}],

View file

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

View file

@ -19,8 +19,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def index_operation do
%Operation{
tags: ["Admin", "Reports"],
summary: "Get a list of reports",
tags: ["Report managment"],
summary: "Retrieve a list of reports",
operationId: "AdminAPI.ReportController.index",
security: [%{"oAuth" => ["read:reports"]}],
parameters: [
@ -69,8 +69,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def show_operation do
%Operation{
tags: ["Admin", "Reports"],
summary: "Get an individual report",
tags: ["Report managment"],
summary: "Retrieve a report",
operationId: "AdminAPI.ReportController.show",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:reports"]}],
@ -83,8 +83,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def update_operation do
%Operation{
tags: ["Admin", "Reports"],
summary: "Change the state of one or multiple reports",
tags: ["Report managment"],
summary: "Change state of specified reports",
operationId: "AdminAPI.ReportController.update",
security: [%{"oAuth" => ["write:reports"]}],
parameters: admin_api_params(),
@ -99,8 +99,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def notes_create_operation do
%Operation{
tags: ["Admin", "Reports"],
summary: "Create report note",
tags: ["Report managment"],
summary: "Add a note to the report",
operationId: "AdminAPI.ReportController.notes_create",
parameters: [id_param() | admin_api_params()],
requestBody:
@ -120,8 +120,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
def notes_delete_operation do
%Operation{
tags: ["Admin", "Reports"],
summary: "Delete report note",
tags: ["Report managment"],
summary: "Delete note attached to the report",
operationId: "AdminAPI.ReportController.notes_delete",
parameters: [
Operation.parameter(:report_id, :path, :string, "Report ID"),

View file

@ -21,8 +21,9 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def index_operation do
%Operation{
tags: ["Admin", "Statuses"],
tags: ["Status administration"],
operationId: "AdminAPI.StatusController.index",
summary: "Get all statuses",
security: [%{"oAuth" => ["read:statuses"]}],
parameters: [
Operation.parameter(
@ -69,8 +70,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def show_operation do
%Operation{
tags: ["Admin", "Statuses"],
summary: "Show Status",
tags: ["Status adminitration)"],
summary: "Get status",
operationId: "AdminAPI.StatusController.show",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:statuses"]}],
@ -83,8 +84,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def update_operation do
%Operation{
tags: ["Admin", "Statuses"],
summary: "Change the scope of an individual reported status",
tags: ["Status adminitration)"],
summary: "Change the scope of a status",
operationId: "AdminAPI.StatusController.update",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}],
@ -98,8 +99,8 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
def delete_operation do
%Operation{
tags: ["Admin", "Statuses"],
summary: "Delete an individual reported status",
tags: ["Status adminitration)"],
summary: "Delete status",
operationId: "AdminAPI.StatusController.delete",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}],

View file

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

View file

@ -20,7 +20,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def mark_as_read_operation do
%Operation{
tags: ["chat"],
tags: ["Chats"],
summary: "Mark all messages in the chat as read",
operationId: "ChatController.mark_as_read",
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
%Operation{
tags: ["chat"],
summary: "Mark one message in the chat as read",
tags: ["Chats"],
summary: "Mark a message as read",
operationId: "ChatController.mark_message_as_read",
parameters: [
Operation.parameter(:id, :path, :string, "The ID of the Chat"),
@ -68,8 +68,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def show_operation do
%Operation{
tags: ["chat"],
summary: "Create a chat",
tags: ["Chats"],
summary: "Retrieve a chat",
operationId: "ChatController.show",
parameters: [
Operation.parameter(
@ -99,7 +99,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def create_operation do
%Operation{
tags: ["chat"],
tags: ["Chats"],
summary: "Create a chat",
operationId: "ChatController.create",
parameters: [
@ -130,8 +130,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def index_operation do
%Operation{
tags: ["chat"],
summary: "Get a list of chats that you participated in",
tags: ["Chats"],
summary: "Retrieve list of chats",
operationId: "ChatController.index",
parameters: [
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
@ -150,8 +150,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def messages_operation do
%Operation{
tags: ["chat"],
summary: "Get the most recent messages of the chat",
tags: ["Chats"],
summary: "Retrieve chat's messages",
operationId: "ChatController.messages",
parameters:
[Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++
@ -175,7 +175,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def post_chat_message_operation do
%Operation{
tags: ["chat"],
tags: ["Chats"],
summary: "Post a message to the chat",
operationId: "ChatController.post_chat_message",
parameters: [
@ -202,8 +202,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def delete_message_operation do
%Operation{
tags: ["chat"],
summary: "delete_message",
tags: ["Chats"],
summary: "Delete message",
operationId: "ChatController.delete_message",
parameters: [
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
%Operation{
tags: ["Conversations"],
summary: "Show conversation",
summary: "List of conversations",
security: [%{"oAuth" => ["read:statuses"]}],
operationId: "ConversationController.index",
parameters: [
@ -44,7 +44,7 @@ defmodule Pleroma.Web.ApiSpec.ConversationOperation do
def mark_as_read_operation do
%Operation{
tags: ["Conversations"],
summary: "Mark as read",
summary: "Mark conversation as read",
operationId: "ConversationController.mark_as_read",
parameters: [
Operation.parameter(:id, :path, :string, "Conversation ID",

View file

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

View file

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

View file

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

View file

@ -16,8 +16,8 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
def index_operation do
%Operation{
tags: ["apps"],
summary: "View all filters",
tags: ["Filters"],
summary: "All filters",
operationId: "FilterController.index",
security: [%{"oAuth" => ["read:filters"]}],
responses: %{
@ -29,7 +29,7 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
def create_operation do
%Operation{
tags: ["apps"],
tags: ["Filters"],
summary: "Create a filter",
operationId: "FilterController.create",
requestBody: Helpers.request_body("Parameters", create_request(), required: true),
@ -43,8 +43,8 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
def show_operation do
%Operation{
tags: ["apps"],
summary: "View all filters",
tags: ["Filters"],
summary: "Filter",
parameters: [id_param()],
operationId: "FilterController.show",
security: [%{"oAuth" => ["read:filters"]}],
@ -58,7 +58,7 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
def update_operation do
%Operation{
tags: ["apps"],
tags: ["Filters"],
summary: "Update a filter",
parameters: [id_param()],
operationId: "FilterController.update",
@ -73,7 +73,7 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
def delete_operation do
%Operation{
tags: ["apps"],
tags: ["Filters"],
summary: "Remove a filter",
parameters: [id_param()],
operationId: "FilterController.delete",

View file

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

View file

@ -14,7 +14,7 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
def show_operation do
%Operation{
tags: ["Instance"],
summary: "Fetch instance",
summary: "Retrieve instance information",
description: "Information about the server",
operationId: "InstanceController.show",
responses: %{
@ -26,7 +26,7 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
def peers_operation do
%Operation{
tags: ["Instance"],
summary: "List of known hosts",
summary: "Retrieve list of known instances",
operationId: "InstanceController.peers",
responses: %{
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
%Operation{
tags: ["Lists"],
summary: "Show user's lists",
summary: "Retrieve a list of lists",
description: "Fetch all lists that the user owns",
security: [%{"oAuth" => ["read:lists"]}],
operationId: "ListController.index",
@ -49,7 +49,7 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
def show_operation do
%Operation{
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.",
operationId: "ListController.show",
parameters: [id_param()],
@ -93,7 +93,7 @@ defmodule Pleroma.Web.ApiSpec.ListOperation do
def list_accounts_operation do
%Operation{
tags: ["Lists"],
summary: "View accounts in list",
summary: "Retrieve accounts in list",
operationId: "ListController.list_accounts",
parameters: [id_param()],
security: [%{"oAuth" => ["read:lists"]}],

View file

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

View file

@ -22,7 +22,7 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
def index_operation do
%Operation{
tags: ["Notifications"],
summary: "Get all notifications",
summary: "Retrieve a list of notifications",
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.",
operationId: "NotificationController.index",
@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
def show_operation do
%Operation{
tags: ["Notifications"],
summary: "Get a single notification",
summary: "Retrieve a notification",
description: "View information about a notification with a given ID.",
operationId: "NotificationController.show",
security: [%{"oAuth" => ["read:notifications"]}],
@ -99,7 +99,7 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
def dismiss_operation do
%Operation{
tags: ["Notifications"],
summary: "Dismiss a single notification",
summary: "Dismiss a notification",
description: "Clear a single notification from the server.",
operationId: "NotificationController.dismiss",
parameters: [id_param()],

View file

@ -18,8 +18,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
def confirmation_resend_operation do
%Operation{
tags: ["Accounts"],
summary: "Resend confirmation email. Expects `email` or `nickname`",
tags: ["Account credentials"],
summary: "Resend confirmation email",
description: "Expects `email` or `nickname`.",
operationId: "PleromaAPI.AccountController.confirmation_resend",
parameters: [
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
%Operation{
tags: ["Accounts"],
summary: "Returns favorites timeline of any user",
tags: ["Retrieve account information"],
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",
parameters: [id_param() | pagination_params()],
security: [%{"oAuth" => ["read:favourites"]}],
@ -61,8 +64,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
def subscribe_operation do
%Operation{
tags: ["Accounts"],
summary: "Subscribe to receive notifications for all statuses posted by a user",
tags: ["Account actions"],
summary: "Subscribe",
description: "Receive notifications for all statuses posted by the account.",
operationId: "PleromaAPI.AccountController.subscribe",
parameters: [id_param()],
security: [%{"oAuth" => ["follow", "write:follows"]}],
@ -75,8 +79,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
def unsubscribe_operation do
%Operation{
tags: ["Accounts"],
summary: "Unsubscribe to stop receiving notifications from user statuses",
tags: ["Account actions"],
summary: "Unsubscribe",
description: "Stop receiving notifications for all statuses posted by the account.",
operationId: "PleromaAPI.AccountController.unsubscribe",
parameters: [id_param()],
security: [%{"oAuth" => ["follow", "write:follows"]}],

View file

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

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def create_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.add_file",
security: [%{"oAuth" => ["write"]}],
@ -62,7 +62,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def update_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.update_file",
security: [%{"oAuth" => ["write"]}],
@ -106,7 +106,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def delete_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Delete emoji file from pack",
operationId: "PleromaAPI.EmojiPackController.delete_file",
security: [%{"oAuth" => ["write"]}],

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def remote_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Make request to another instance for emoji packs list",
security: [%{"oAuth" => ["write"]}],
parameters: [
@ -44,7 +44,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def index_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Lists local custom emoji packs",
operationId: "PleromaAPI.EmojiPackController.index",
parameters: [
@ -69,7 +69,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def show_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Show emoji pack",
operationId: "PleromaAPI.EmojiPackController.show",
parameters: [
@ -97,7 +97,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def archive_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Requests a local pack archive from the instance",
operationId: "PleromaAPI.EmojiPackController.archive",
parameters: [name_param()],
@ -115,7 +115,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def download_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Download pack from another instance",
operationId: "PleromaAPI.EmojiPackController.download",
security: [%{"oAuth" => ["write"]}],
@ -145,7 +145,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def create_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Create an empty pack",
operationId: "PleromaAPI.EmojiPackController.create",
security: [%{"oAuth" => ["write"]}],
@ -161,7 +161,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def delete_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Delete a custom emoji pack",
operationId: "PleromaAPI.EmojiPackController.delete",
security: [%{"oAuth" => ["write"]}],
@ -177,7 +177,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def update_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Updates (replaces) pack metadata",
operationId: "PleromaAPI.EmojiPackController.update",
security: [%{"oAuth" => ["write"]}],
@ -193,7 +193,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def import_from_filesystem_operation do
%Operation{
tags: ["Emoji Packs"],
tags: ["Emoji packs"],
summary: "Imports packs from filesystem",
operationId: "PleromaAPI.EmojiPackController.import",
security: [%{"oAuth" => ["write"]}],

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -22,8 +22,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def index_operation do
%Operation{
tags: ["Statuses"],
summary: "Get multiple statuses by IDs",
tags: ["Retrieve status information"],
summary: "Multiple statuses",
security: [%{"oAuth" => ["read:statuses"]}],
parameters: [
Operation.parameter(
@ -48,7 +48,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def create_operation do
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Publish new status",
security: [%{"oAuth" => ["write:statuses"]}],
description: "Post a new status",
@ -68,8 +68,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def show_operation do
%Operation{
tags: ["Statuses"],
summary: "View specific status",
tags: ["Retrieve status information"],
summary: "Status",
description: "View information about a status",
operationId: "StatusController.show",
security: [%{"oAuth" => ["read:statuses"]}],
@ -91,8 +91,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def delete_operation do
%Operation{
tags: ["Statuses"],
summary: "Delete status",
tags: ["Status actions"],
summary: "Delete",
security: [%{"oAuth" => ["write:statuses"]}],
description: "Delete one of your own statuses",
operationId: "StatusController.delete",
@ -107,8 +107,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def reblog_operation do
%Operation{
tags: ["Statuses"],
summary: "Boost",
tags: ["Status actions"],
summary: "Reblog",
security: [%{"oAuth" => ["write:statuses"]}],
description: "Share a status",
operationId: "StatusController.reblog",
@ -129,8 +129,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unreblog_operation do
%Operation{
tags: ["Statuses"],
summary: "Undo boost",
tags: ["Status actions"],
summary: "Undo reblog",
security: [%{"oAuth" => ["write:statuses"]}],
description: "Undo a reshare of a status",
operationId: "StatusController.unreblog",
@ -144,7 +144,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def favourite_operation do
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Favourite",
security: [%{"oAuth" => ["write:favourites"]}],
description: "Add a status to your favourites list",
@ -159,7 +159,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unfavourite_operation do
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Undo favourite",
security: [%{"oAuth" => ["write:favourites"]}],
description: "Remove a status from your favourites list",
@ -174,7 +174,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def pin_operation do
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Pin to profile",
security: [%{"oAuth" => ["write:accounts"]}],
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
%Operation{
tags: ["Statuses"],
summary: "Unpin to profile",
tags: ["Status actions"],
summary: "Unpin from profile",
security: [%{"oAuth" => ["write:accounts"]}],
description: "Unfeature a status from the top of your profile",
operationId: "StatusController.unpin",
@ -204,7 +204,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def bookmark_operation do
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Bookmark",
security: [%{"oAuth" => ["write:bookmarks"]}],
description: "Privately bookmark a status",
@ -218,7 +218,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def unbookmark_operation do
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Undo bookmark",
security: [%{"oAuth" => ["write:bookmarks"]}],
description: "Remove a status from your private bookmarks",
@ -232,7 +232,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def mute_conversation_operation do
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Mute conversation",
security: [%{"oAuth" => ["write:mutes"]}],
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
%Operation{
tags: ["Statuses"],
tags: ["Status actions"],
summary: "Unmute conversation",
security: [%{"oAuth" => ["write:mutes"]}],
description:
@ -283,7 +283,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def card_operation do
%Operation{
tags: ["Statuses"],
tags: ["Retrieve status information"],
deprecated: true,
summary: "Preview card",
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
%Operation{
tags: ["Statuses"],
tags: ["Retrieve status information"],
summary: "Favourited by",
description: "View who favourited a given status",
operationId: "StatusController.favourited_by",
@ -331,9 +331,9 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def reblogged_by_operation do
%Operation{
tags: ["Statuses"],
summary: "Boosted by",
description: "View who boosted a given status",
tags: ["Retrieve status information"],
summary: "Reblogged by",
description: "View who reblogged a given status",
operationId: "StatusController.reblogged_by",
security: [%{"oAuth" => ["read:accounts"]}],
parameters: [id_param()],
@ -351,7 +351,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def context_operation do
%Operation{
tags: ["Statuses"],
tags: ["Retrieve status information"],
summary: "Parent and child statuses",
description: "View statuses above and below this status in the thread",
operationId: "StatusController.context",
@ -365,7 +365,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def favourites_operation do
%Operation{
tags: ["Statuses"],
tags: ["Timelines"],
summary: "Favourited statuses",
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.",
@ -380,7 +380,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
def bookmarks_operation do
%Operation{
tags: ["Statuses"],
tags: ["Timelines"],
summary: "Bookmarked statuses",
description: "Statuses the user has bookmarked",
operationId: "StatusController.bookmarks",
@ -413,34 +413,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
items: %Schema{type: :string},
description: "Array of Attachment ids to be attached as media."
},
poll: %Schema{
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?"
}
}
},
poll: poll_params(),
in_reply_to_id: %Schema{
nullable: true,
allOf: [FlakeID],
@ -522,6 +495,37 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
}
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
Operation.parameter(:id, :path, FlakeID, "Status ID",
example: "9umDrYheeY451cQnEe",

View file

@ -17,7 +17,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
def create_operation do
%Operation{
tags: ["Push Subscriptions"],
tags: ["Push subscriptions"],
summary: "Subscribe to push notifications",
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.",
@ -25,7 +25,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
security: [%{"oAuth" => ["push"]}],
requestBody: Helpers.request_body("Parameters", create_request(), required: true),
responses: %{
200 => Operation.response("Push Subscription", "application/json", PushSubscription),
200 => Operation.response("Push subscription", "application/json", PushSubscription),
400 => 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
%Operation{
tags: ["Push Subscriptions"],
tags: ["Push subscriptions"],
summary: "Get current subscription",
description: "View the PushSubscription currently associated with this access token.",
operationId: "SubscriptionController.show",
security: [%{"oAuth" => ["push"]}],
responses: %{
200 => Operation.response("Push Subscription", "application/json", PushSubscription),
200 => Operation.response("Push subscription", "application/json", PushSubscription),
403 => 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
%Operation{
tags: ["Push Subscriptions"],
tags: ["Push subscriptions"],
summary: "Change types of notifications",
description:
"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"]}],
requestBody: Helpers.request_body("Parameters", update_request(), required: true),
responses: %{
200 => Operation.response("Push Subscription", "application/json", PushSubscription),
200 => Operation.response("Push subscription", "application/json", PushSubscription),
403 => Operation.response("Error", "application/json", ApiError)
}
}
@ -65,7 +65,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
def delete_operation do
%Operation{
tags: ["Push Subscriptions"],
tags: ["Push subscriptions"],
summary: "Remove current subscription",
description: "Removes the current Web Push API subscription.",
operationId: "SubscriptionController.delete",

View file

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

View file

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

View file

@ -5,8 +5,8 @@
defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.Attachment
alias Pleroma.Web.ApiSpec.Schemas.Poll
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
alias Pleroma.Web.ApiSpec.StatusOperation
require OpenApiSpex
@ -29,7 +29,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
spoiler_text: %Schema{type: :string, nullable: true},
visibility: %Schema{allOf: [VisibilityScope], 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}
}
}

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
# 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
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,
at: "/",
gzip: true,

View file

@ -269,10 +269,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
def relationships(%{assigns: %{user: _user}} = conn, _), do: json(conn, [])
@doc "GET /api/v1/accounts/:id"
def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id}) do
def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id} = params) do
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user),
:visible <- User.visible_for(user, for_user) do
render(conn, "show.json", user: user, for: for_user)
render(conn, "show.json",
user: user,
for: for_user,
embed_relationships: embed_relationships?(params)
)
else
error -> user_visibility_error(conn, error)
end
@ -454,7 +458,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
conn
|> add_link_headers(users)
|> render("index.json", users: users, for: user, as: :user)
|> render("index.json",
users: users,
for: user,
as: :user,
embed_relationships: embed_relationships?(params)
)
end
@doc "GET /api/v1/blocks"

View file

@ -51,6 +51,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:reply_filtering_user, user)
|> Map.put(:announce_filtering_user, user)
|> Map.put(:user, user)
|> Map.put(:local_only, params[:local])
|> Map.delete(:local)
activities =
[user.ap_id | User.following(user)]
@ -190,6 +192,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:blocking_user, user)
|> Map.put(:user, user)
|> Map.put(:muting_user, user)
|> Map.put(:local_only, params[:local])
# we must filter the following list for the user to avoid leaking statuses the user
# does not actually have permission to see (for more info, peruse security issue #270).

View file

@ -262,7 +262,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
}
},
# Pleroma extension
# Pleroma extensions
# Note: it's insecure to output :email but fully-qualified nickname may serve as safe stub
fqn: User.full_nickname(user),
pleroma: %{
ap_id: user.ap_id,
also_known_as: user.also_known_as,

View file

@ -45,6 +45,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
fields_limits: fields_limits(),
post_formats: Config.get([:instance, :allowed_post_formats])
},
stats: %{mau: Pleroma.User.active_user_count()},
vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
}
}

View file

@ -20,9 +20,26 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
end
end
defp headers do
def primary_frontend do
with %{"name" => frontend} <- Config.get([:frontends, :primary]),
available <- Config.get([:frontends, :available]),
%{} = primary_frontend <- Map.get(available, frontend) do
{:ok, primary_frontend}
end
end
def custom_http_frontend_headers do
with {:ok, %{"custom-http-headers" => custom_headers}} <- primary_frontend() do
custom_headers
else
_ -> []
end
end
def headers do
referrer_policy = Config.get([:http_security, :referrer_policy])
report_uri = Config.get([:http_security, :report_uri])
custom_http_frontend_headers = custom_http_frontend_headers()
headers = [
{"x-xss-protection", "1; mode=block"},
@ -34,6 +51,13 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
{"content-security-policy", csp_string()}
]
headers =
if custom_http_frontend_headers do
custom_http_frontend_headers ++ headers
else
headers
end
if report_uri do
report_group = %{
"group" => "csp-endpoint",

View file

@ -0,0 +1,30 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.UserTrackingPlug do
alias Pleroma.User
import Plug.Conn, only: [assign: 3]
@update_interval :timer.hours(24)
def init(opts), do: opts
def call(%{assigns: %{user: %User{id: id} = user}} = conn, _) when not is_nil(id) do
with true <- needs_update?(user),
{:ok, user} <- User.update_last_active_at(user) do
assign(conn, :user, user)
else
_ -> conn
end
end
def call(conn, _), do: conn
defp needs_update?(%User{last_active_at: nil}), do: true
defp needs_update?(%User{last_active_at: last_active_at}) do
NaiveDateTime.diff(NaiveDateTime.utc_now(), last_active_at, :millisecond) >= @update_interval
end
end

View file

@ -56,6 +56,7 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.UserEnabledPlug)
plug(Pleroma.Web.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug)
plug(Pleroma.Web.Plugs.UserTrackingPlug)
end
pipeline :base_api do
@ -319,6 +320,8 @@ defmodule Pleroma.Web.Router do
end
scope "/oauth", Pleroma.Web.OAuth do
# Note: use /api/v1/accounts/verify_credentials for userinfo of signed-in user
get("/registration_details", OAuthController, :registration_details)
post("/mfa/verify", MFAController, :verify, as: :mfa_verify)

View file

@ -6,7 +6,7 @@
</div>
<span class="display-name" style="padding-left: 0.5em;">
<bdi><%= raw (@author.name |> Formatter.emojify(@author.emoji)) %></bdi>
<span class="nickname"><%= full_nickname(@author) %></span>
<span class="nickname">@<%= full_nickname(@author) %></span>
</span>
</a>
</div>

View file

@ -17,6 +17,8 @@ defmodule Pleroma.Web.EmbedView do
use Phoenix.HTML
defdelegate full_nickname(user), to: User
@media_types ["image", "audio", "video"]
defp fetch_media_type(%{"mediaType" => mediaType}) do
@ -30,11 +32,6 @@ defmodule Pleroma.Web.EmbedView do
)
end
defp full_nickname(user) do
%{host: host} = URI.parse(user.ap_id)
"@" <> user.nickname <> "@" <> host
end
defp status_title(%Activity{object: %Object{data: %{"name" => name}}}) when is_binary(name),
do: name

View file

@ -17,12 +17,14 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do
"object" => %{"data" => %{"attachment" => [_ | _] = attachments, "actor" => actor}}
}
}) do
if Pleroma.Config.get([:instance, :cleanup_attachments], false) do
attachments
|> Enum.flat_map(fn item -> Enum.map(item["url"], & &1["href"]) end)
|> fetch_objects
|> prepare_objects(actor, Enum.map(attachments, & &1["name"]))
|> filter_objects
|> do_clean
end
{:ok, :success}
end

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Workers.PurgeExpiredActivity do
Worker which purges expired activity.
"""
use Oban.Worker, queue: :activity_expiration, max_attempts: 1
use Oban.Worker, queue: :activity_expiration, max_attempts: 1, unique: [period: :infinity]
import Ecto.Query

View file

@ -9,38 +9,50 @@ defmodule Pleroma.Workers.ScheduledActivityWorker do
use Pleroma.Workers.WorkerHelper, queue: "scheduled_activities"
alias Pleroma.Config
alias Pleroma.Repo
alias Pleroma.ScheduledActivity
alias Pleroma.User
alias Pleroma.Web.CommonAPI
require Logger
@impl Oban.Worker
def perform(%Job{args: %{"activity_id" => activity_id}}) do
if Config.get([ScheduledActivity, :enabled]) do
case Pleroma.Repo.get(ScheduledActivity, activity_id) do
%ScheduledActivity{} = scheduled_activity ->
post_activity(scheduled_activity)
with %ScheduledActivity{} = scheduled_activity <- find_scheduled_activity(activity_id),
%User{} = user <- find_user(scheduled_activity.user_id) do
params = atomize_keys(scheduled_activity.params)
_ ->
Logger.error("#{__MODULE__} Couldn't find scheduled activity: #{activity_id}")
end
end
end
defp post_activity(%ScheduledActivity{user_id: user_id, params: params} = scheduled_activity) do
params = Map.new(params, fn {key, value} -> {String.to_existing_atom(key), value} end)
with {:delete, {:ok, _}} <- {:delete, ScheduledActivity.delete(scheduled_activity)},
{:user, %User{} = user} <- {:user, User.get_cached_by_id(user_id)},
{:post, {:ok, _}} <- {:post, CommonAPI.post(user, params)} do
:ok
Repo.transaction(fn ->
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, params)
{:ok, _} = ScheduledActivity.delete(scheduled_activity)
activity
end)
else
error ->
Logger.error(
"#{__MODULE__} Couldn't create a status from the scheduled activity: #{inspect(error)}"
)
{:error, :scheduled_activity_not_found} = error ->
Logger.error("#{__MODULE__} Couldn't find scheduled activity: #{activity_id}")
error
{:error, :user_not_found} = error ->
Logger.error("#{__MODULE__} Couldn't find user for scheduled activity: #{activity_id}")
error
end
end
defp find_scheduled_activity(id) do
with nil <- Repo.get(ScheduledActivity, id) do
{:error, :scheduled_activity_not_found}
end
end
defp find_user(id) do
with nil <- User.get_cached_by_id(id) do
{:error, :user_not_found}
end
end
defp atomize_keys(map) do
Map.new(map, fn
{key, value} when is_map(value) -> {String.to_existing_atom(key), atomize_keys(value)}
{key, value} -> {String.to_existing_atom(key), value}
end)
end
end

View file

@ -194,7 +194,7 @@ defmodule Pleroma.Mixfile do
{:restarter, path: "./restarter"},
{:majic,
git: "https://git.pleroma.social/pleroma/elixir-libraries/majic.git",
ref: "4c692e544b28d1f5e543fb8a44be090f8cd96f80"},
ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"},
{:open_api_spex,
git: "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git",
ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"},

View file

@ -66,7 +66,7 @@
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
"libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"},
"linkify": {:hex, :linkify, "0.4.1", "f881eb3429ae88010cf736e6fb3eed406c187bcdd544902ec937496636b7c7b3", [:mix], [], "hexpm", "ce98693f54ae9ace59f2f7a8aed3de2ef311381a8ce7794804bd75484c371dda"},
"majic": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", "4c692e544b28d1f5e543fb8a44be090f8cd96f80", [ref: "4c692e544b28d1f5e543fb8a44be090f8cd96f80"]},
"majic": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", "289cda1b6d0d70ccb2ba508a2b0bd24638db2880", [ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"]},
"makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},

View file

@ -0,0 +1,11 @@
defmodule Pleroma.Repo.Migrations.AddLastActiveAtToUsers do
use Ecto.Migration
def change do
alter table(:users) do
add(:last_active_at, :naive_datetime)
end
create_if_not_exists(index(:users, [:last_active_at]))
end
end

View file

@ -0,0 +1,29 @@
defmodule Pleroma.Repo.Migrations.RemoveDuplicatesFromActivityExpirationQueue do
use Ecto.Migration
import Ecto.Query, only: [from: 2]
def up do
duplicate_ids =
from(j in Oban.Job,
where: j.queue == "activity_expiration",
where: j.worker == "Pleroma.Workers.PurgeExpiredActivity",
where: j.state == "scheduled",
select:
{fragment("(?)->>'activity_id'", j.args), fragment("array_agg(?)", j.id), count(j.id)},
group_by: fragment("(?)->>'activity_id'", j.args),
having: count(j.id) > 1
)
|> Pleroma.Repo.all()
|> Enum.map(fn {_, ids, _} ->
max_id = Enum.max(ids)
List.delete(ids, max_id)
end)
|> List.flatten()
from(j in Oban.Job, where: j.id in ^duplicate_ids)
|> Pleroma.Repo.delete_all()
end
def down, do: :noop
end

View file

@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.9a4c5ede37b2f0230836.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.54838a79dee084ec3dad.js></script><script type=text/javascript src=/static/js/app.eb8f7164fc75862a251d.js></script></body></html>
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.9a4c5ede37b2f0230836.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.3b02e2e5bd8cdca42216.js></script><script type=text/javascript src=/static/js/app.c6b8a1c86149ed63e6ff.js></script></body></html>

View file

@ -1 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/12.c6df5166dc6cdcf749e5.js","sourceRoot":""}
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/10.8702741bef65422a8655.js","sourceRoot":""}

View file

@ -1 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/10.a11a612e4c1ef51ded17.js","sourceRoot":""}
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/11.a3e462fd9190986433f8.js","sourceRoot":""}

View file

@ -1 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/13.77214c18c6d2a9865281.js","sourceRoot":""}
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/12.7d5889019e7177d19bc2.js","sourceRoot":""}

View file

@ -1 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/11.22872a1f83121e70a148.js","sourceRoot":""}
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/13.bb129366e7d54b5678d4.js","sourceRoot":""}

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/14.3546063198fc4cb3852c.js","sourceRoot":""}

View file

@ -1 +0,0 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/14.e560f5e2f902b9ad2d0d.js","sourceRoot":""}

View file

@ -1 +0,0 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/15.2893c12f1ca2bcdc3cbf.js","sourceRoot":""}

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/15.e0cc6ce336f523c26f4d.js","sourceRoot":""}

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/16.67b2bcf7dd3271e31643.js","sourceRoot":""}

View file

@ -1 +0,0 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/16.be7f4b788716bec25023.js","sourceRoot":""}

View file

@ -1 +0,0 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/17.4ddba89b4f8c284f6392.js","sourceRoot":""}

View file

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{584:function(e){e.exports={finder:{error_fetching_user:"Hiba felhasználó beszerzésével",find_user:"Felhasználó keresése"},general:{submit:"Elküld"},login:{login:"Bejelentkezés",logout:"Kijelentkezés",password:"Jelszó",placeholder:"e.g. lain",register:"Feliratkozás",username:"Felhasználó név"},nav:{mentions:"Említéseim",public_tl:"Publikus Idővonal",timeline:"Idővonal",twkn:"Az Egész Ismert Hálózat"},notifications:{followed_you:"követ téged",notifications:"Értesítések",read:"Olvasva!"},post_status:{default:"Most érkeztem L.A.-be",posting:"Küldés folyamatban"},registration:{bio:"Bio",email:"Email",fullname:"Teljes név",password_confirm:"Jelszó megerősítése",registration:"Feliratkozás"},settings:{attachments:"Csatolmányok",avatar:"Avatár",bio:"Bio",current_avatar:"Jelenlegi avatár",current_profile_banner:"Jelenlegi profil banner",filtering:"Szűrés",filtering_explanation:"Minden tartalom mely ezen szavakat tartalmazza némítva lesz, soronként egy",hide_attachments_in_convo:"Csatolmányok elrejtése a társalgásokban",hide_attachments_in_tl:"Csatolmányok elrejtése az idővonalon",name:"Név",name_bio:"Név és Bio",nsfw_clickthrough:"NSFW átkattintási tartalom elrejtésének engedélyezése",profile_background:"Profil háttérkép",profile_banner:"Profil Banner",set_new_avatar:"Új avatár",set_new_profile_background:"Új profil háttér beállítása",set_new_profile_banner:"Új profil banner",settings:"Beállítások",theme:"Téma",user_settings:"Felhasználói beállítások"},timeline:{conversation:"Társalgás",error_fetching:"Hiba a frissítések beszerzésénél",load_older:"Régebbi állapotok betöltése",show_new:"Újak mutatása",up_to_date:"Naprakész"},user_card:{block:"Letilt",blocked:"Letiltva!",follow:"Követ",followees:"Követettek",followers:"Követők",following:"Követve!",follows_you:"Követ téged!",mute:"Némít",muted:"Némított",per_day:"naponta",statuses:"Állapotok"}}}}]);
//# sourceMappingURL=17.4ddba89b4f8c284f6392.js.map
(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{585:function(e){e.exports={finder:{error_fetching_user:"Hiba felhasználó beszerzésével",find_user:"Felhasználó keresése"},general:{submit:"Elküld"},login:{login:"Bejelentkezés",logout:"Kijelentkezés",password:"Jelszó",placeholder:"e.g. lain",register:"Feliratkozás",username:"Felhasználó név"},nav:{mentions:"Említéseim",public_tl:"Publikus Idővonal",timeline:"Idővonal",twkn:"Az Egész Ismert Hálózat"},notifications:{followed_you:"követ téged",notifications:"Értesítések",read:"Olvasva!"},post_status:{default:"Most érkeztem L.A.-be",posting:"Küldés folyamatban"},registration:{bio:"Bio",email:"Email",fullname:"Teljes név",password_confirm:"Jelszó megerősítése",registration:"Feliratkozás"},settings:{attachments:"Csatolmányok",avatar:"Avatár",bio:"Bio",current_avatar:"Jelenlegi avatár",current_profile_banner:"Jelenlegi profil banner",filtering:"Szűrés",filtering_explanation:"Minden tartalom mely ezen szavakat tartalmazza némítva lesz, soronként egy",hide_attachments_in_convo:"Csatolmányok elrejtése a társalgásokban",hide_attachments_in_tl:"Csatolmányok elrejtése az idővonalon",name:"Név",name_bio:"Név és Bio",nsfw_clickthrough:"NSFW átkattintási tartalom elrejtésének engedélyezése",profile_background:"Profil háttérkép",profile_banner:"Profil Banner",set_new_avatar:"Új avatár",set_new_profile_background:"Új profil háttér beállítása",set_new_profile_banner:"Új profil banner",settings:"Beállítások",theme:"Téma",user_settings:"Felhasználói beállítások"},timeline:{conversation:"Társalgás",error_fetching:"Hiba a frissítések beszerzésénél",load_older:"Régebbi állapotok betöltése",show_new:"Újak mutatása",up_to_date:"Naprakész"},user_card:{block:"Letilt",blocked:"Letiltva!",follow:"Követ",followees:"Követettek",followers:"Követők",following:"Követve!",follows_you:"Követ téged!",mute:"Némít",muted:"Némított",per_day:"naponta",statuses:"Állapotok"}}}}]);
//# sourceMappingURL=17.a8395e49508cd81ecdf4.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/17.a8395e49508cd81ecdf4.js","sourceRoot":""}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/18.1b9a9aedd06803dbb3e4.js","sourceRoot":""}

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/18.990b88b57bf3a6809098.js","sourceRoot":""}

View file

@ -1 +0,0 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/19.783715f17e3f98e8898e.js","sourceRoot":""}

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/19.af8826ed7cd146d80620.js","sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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