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

This commit is contained in:
a1batross 2021-03-05 10:26:57 +01:00
commit 06ae903e8e
217 changed files with 1994 additions and 952 deletions

4
.gitignore vendored
View File

@ -53,3 +53,7 @@ pleroma.iml
# asdf
.tool-versions
# Editor temp files
/*~
/*#

View File

@ -369,3 +369,26 @@ docker-release:
- dind
only:
- /^release/.*$/@pleroma/pleroma
docker-adhoc:
stage: docker
image: docker:latest
cache: {}
dependencies: []
variables: *docker-variables
before_script: *before-docker
allow_failure: true
script:
script:
- mkdir -p /root/.docker/cli-plugins
- wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
- echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
- chmod +x ~/.docker/cli-plugins/docker-buildx
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- docker buildx create --name mbuilder --driver docker-container --use
- docker buildx inspect --bootstrap
- docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
tags:
- dind
only:
- /^build-docker/.*$/@pleroma/pleroma

View File

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

View File

@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased
- The `application` metadata returned with statuses is no longer hardcoded. Apps that want to display these details will now have valid data for new posts after this change.
## Unreleased (Patch)
## [2.3.0] - 2020-03-01
### Security
- Fixed client user agent leaking through MediaProxy
### Removed
- `:auth, :enforce_oauth_admin_scope_usage` configuration option.
### Changed
- **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
@ -21,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Provide redirect of external posts from `/notice/:id` to their original URL
- Admins no longer receive notifications for reports if they are the actor making the report.
- Improved Mailer configuration setting descriptions for AdminFE.
- Updated default avatar to look nicer.
<details>
<summary>API Changes</summary>
@ -31,13 +46,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Breaking:** AdminAPI `GET /api/pleroma/admin/users/:nickname_or_id/statuses` changed response format and added the number of total users posts.
- **Breaking:** AdminAPI `GET /api/pleroma/admin/instances/:instance/statuses` changed response format and added the number of total users posts.
- Admin API: Reports now ordered by newest
- Pleroma API: `GET /api/v1/pleroma/chats` is deprecated in favor of `GET /api/v2/pleroma/chats`.
- Pleroma API: Reroute `/api/pleroma/*` to `/api/v1/pleroma/*`
</details>
### Added
- Reports now generate notifications for admins and mods.
- Experimental websocket-based federation between Pleroma instances.
- Support for local-only statuses.
- Support pagination of blocks and mutes.
- Account backup.
@ -57,6 +73,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
<details>
<summary>API Changes</summary>
- Admin API: (`GET /api/pleroma/admin/users`) filter users by `unconfirmed` status and `actor_type`.
- Pleroma API: `GET /api/v2/pleroma/chats` added. It is exactly like `GET /api/v1/pleroma/chats` except supports pagination.
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
@ -66,6 +83,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: Add monthly active users to `/api/v1/instance` (`pleroma.stats.mau`).
- Mastodon API: Home, public, hashtag & list timelines accept `only_media`, `remote` & `local` parameters for filtration.
- Mastodon API: `/api/v1/accounts/:id` & `/api/v1/mutes` endpoints accept `with_relationships` parameter and return filled `pleroma.relationship` field.
- Mastodon API: Endpoint to remove a conversation (`DELETE /api/v1/conversations/:id`).
- Mastodon API: `expires_in` in the scheduled post `params` field on `/api/v1/statuses` and `/api/v1/scheduled_statuses/:id` endpoints.
</details>
### Fixed
@ -89,9 +108,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: Support for expires_in/expires_at in the Filters.
</details>
## Unreleased (Patch)
## [2.2.2] - 2020-01-18
### Fixed

View File

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

View File

@ -611,10 +611,7 @@ config :ueberauth,
base_path: "/oauth",
providers: ueberauth_providers
config :pleroma,
:auth,
enforce_oauth_admin_scope_usage: true,
oauth_consumer_strategies: oauth_consumer_strategies
config :pleroma, :auth, oauth_consumer_strategies: oauth_consumer_strategies
config :pleroma, Pleroma.Emails.Mailer, adapter: Swoosh.Adapters.Sendmail, enabled: false

View File

@ -38,7 +38,7 @@ config :pleroma, :instance,
external_user_synchronization: false,
static_dir: "test/instance_static/"
config :pleroma, :activitypub, sign_object_fetches: false
config :pleroma, :activitypub, sign_object_fetches: false, follow_handshake_timeout: 0
# Configure your database
config :pleroma, Pleroma.Repo,

View File

@ -17,7 +17,7 @@ Feel free to contact us to be added to this list!
- Features: MastoAPI
### Whalebird
- Homepage: <https://whalebird.org/>
- Homepage: <https://whalebird.social/>
- Source Code: <https://github.com/h3poteto/whalebird-desktop>
- Contact: [@h3poteto@pleroma.io](https://pleroma.io/users/h3poteto)
- Platforms: Windows, Mac, Linux

View File

@ -49,7 +49,7 @@ To add configuration to your config file, you can copy it from the base config.
* `attachment_links`: Set to true to enable automatically adding attachment link text to statuses.
* `max_report_comment_size`: The maximum size of the report comment (Default: `1000`).
* `safe_dm_mentions`: If set to true, only mentions at the beginning of a post will be used to address people in direct messages. This is to prevent accidental mentioning of people when talking about them (e.g. "@friend hey i really don't like @enemy"). Default: `false`.
* `healthcheck`: If set to true, system data will be shown on ``/api/pleroma/healthcheck``.
* `healthcheck`: If set to true, system data will be shown on ``/api/v1/pleroma/healthcheck``.
* `remote_post_retention_days`: The default amount of days to retain remote posts when pruning the database.
* `user_bio_length`: A user bio maximum length (default: `5000`).
* `user_name_length`: A user name maximum length (default: `100`).
@ -225,7 +225,7 @@ config :pleroma, :mrf_user_allowlist, %{
This can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for `pleroma_fe` and `masto_fe` are configured. You can find the documentation for `pleroma_fe` configuration into [Pleroma-FE configuration and customization for instance administrators](/frontend/CONFIGURATION/#options).
Frontends can access these settings at `/api/pleroma/frontend_configurations`
Frontends can access these settings at `/api/v1/pleroma/frontend_configurations`
To add your own configuration for PleromaFE, use it like this:
@ -848,13 +848,13 @@ config :pleroma, :admin_token, "somerandomtoken"
You can then do
```shell
curl "http://localhost:4000/api/pleroma/admin/users/invites?admin_token=somerandomtoken"
curl "http://localhost:4000/api/v1/pleroma/admin/users/invites?admin_token=somerandomtoken"
```
or
```shell
curl -H "X-Admin-Token: somerandomtoken" "http://localhost:4000/api/pleroma/admin/users/invites"
curl -H "X-Admin-Token: somerandomtoken" "http://localhost:4000/api/v1/pleroma/admin/users/invites"
```
Warning: it's discouraged to use this feature because of the associated security risk: static / rarely changed instance-wide token is much weaker compared to email-password pair of a real admin user; consider using HTTP Basic Auth or OAuth-based authentication instead.

View File

@ -2,14 +2,9 @@
Authentication is required and the user must be an admin.
Configuration options:
The `/api/v1/pleroma/admin/*` path is backwards compatible with `/api/pleroma/admin/*` (`/api/pleroma/admin/*` will be deprecated in the future).
* `[:auth, :enforce_oauth_admin_scope_usage]` — OAuth admin scope requirement toggle.
If `true`, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes).
If `false` and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions.
Note that client app needs to explicitly support admin scopes and request them when obtaining auth token.
## `GET /api/pleroma/admin/users`
## `GET /api/v1/pleroma/admin/users`
### List users
@ -30,7 +25,7 @@ Configuration options:
- *optional* `actor_types`: **[string]** actor type list (`Person`, `Service`, `Application`)
- *optional* `name`: **string** user display name
- *optional* `email`: **string** user email
- Example: `https://mypleroma.org/api/pleroma/admin/users?query=john&filters=local,active&page=1&page_size=10&tags[]=some_tag&tags[]=another_tag&name=display_name&email=email@example.com`
- Example: `https://mypleroma.org/api/v1/pleroma/admin/users?query=john&filters=local,active&page=1&page_size=10&tags[]=some_tag&tags[]=another_tag&name=display_name&email=email@example.com`
- Response:
```json
@ -59,7 +54,7 @@ Configuration options:
}
```
## DEPRECATED `DELETE /api/pleroma/admin/users`
## DEPRECATED `DELETE /api/v1/pleroma/admin/users`
### Remove a user
@ -67,7 +62,7 @@ Configuration options:
- `nickname`
- Response: Users nickname
## `DELETE /api/pleroma/admin/users`
## `DELETE /api/v1/pleroma/admin/users`
### Remove a user
@ -88,7 +83,7 @@ Configuration options:
]
- Response: Users nickname
## `POST /api/pleroma/admin/users/follow`
## `POST /api/v1/pleroma/admin/users/follow`
### Make a user follow another user
@ -98,7 +93,7 @@ Configuration options:
- Response:
- "ok"
## `POST /api/pleroma/admin/users/unfollow`
## `POST /api/v1/pleroma/admin/users/unfollow`
### Make a user unfollow another user
@ -108,7 +103,7 @@ Configuration options:
- Response:
- "ok"
## `PATCH /api/pleroma/admin/users/:nickname/toggle_activation`
## `PATCH /api/v1/pleroma/admin/users/:nickname/toggle_activation`
### Toggle user activation
@ -124,7 +119,7 @@ Configuration options:
}
```
## `PUT /api/pleroma/admin/users/tag`
## `PUT /api/v1/pleroma/admin/users/tag`
### Tag a list of users
@ -132,7 +127,7 @@ Configuration options:
- `nicknames` (array)
- `tags` (array)
## `DELETE /api/pleroma/admin/users/tag`
## `DELETE /api/v1/pleroma/admin/users/tag`
### Untag a list of users
@ -140,7 +135,7 @@ Configuration options:
- `nicknames` (array)
- `tags` (array)
## `GET /api/pleroma/admin/users/:nickname/permission_group`
## `GET /api/v1/pleroma/admin/users/:nickname/permission_group`
### Get user user permission groups membership
@ -154,7 +149,7 @@ Configuration options:
}
```
## `GET /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
## `GET /api/v1/pleroma/admin/users/:nickname/permission_group/:permission_group`
Note: Available `:permission_group` is currently moderator and admin. 404 is returned when the permission group doesnt exist.
@ -170,7 +165,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
}
```
## DEPRECATED `POST /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
## DEPRECATED `POST /api/v1/pleroma/admin/users/:nickname/permission_group/:permission_group`
### Add user to permission group
@ -179,7 +174,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- On failure: `{"error": "…"}`
- On success: JSON of the user
## `POST /api/pleroma/admin/users/permission_group/:permission_group`
## `POST /api/v1/pleroma/admin/users/permission_group/:permission_group`
### Add users to permission group
@ -189,9 +184,9 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- On failure: `{"error": "…"}`
- On success: JSON of the user
## DEPRECATED `DELETE /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
## DEPRECATED `DELETE /api/v1/pleroma/admin/users/:nickname/permission_group/:permission_group`
## `DELETE /api/pleroma/admin/users/:nickname/permission_group/:permission_group`
## `DELETE /api/v1/pleroma/admin/users/:nickname/permission_group/:permission_group`
### Remove user from permission group
@ -201,7 +196,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- On success: JSON of the user
- Note: An admin cannot revoke their own admin status.
## `DELETE /api/pleroma/admin/users/permission_group/:permission_group`
## `DELETE /api/v1/pleroma/admin/users/permission_group/:permission_group`
### Remove users from permission group
@ -212,7 +207,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- On success: JSON of the user
- Note: An admin cannot revoke their own admin status.
## `PATCH /api/pleroma/admin/users/activate`
## `PATCH /api/v1/pleroma/admin/users/activate`
### Activate user
@ -230,7 +225,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
}
```
## `PATCH /api/pleroma/admin/users/deactivate`
## `PATCH /api/v1/pleroma/admin/users/deactivate`
### Deactivate user
@ -248,7 +243,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
}
```
## `PATCH /api/pleroma/admin/users/approve`
## `PATCH /api/v1/pleroma/admin/users/approve`
### Approve user
@ -266,7 +261,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
}
```
## `GET /api/pleroma/admin/users/:nickname_or_id`
## `GET /api/v1/pleroma/admin/users/:nickname_or_id`
### Retrive the details of a user
@ -276,7 +271,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- On failure: `Not found`
- On success: JSON of the user
## `GET /api/pleroma/admin/users/:nickname_or_id/statuses`
## `GET /api/v1/pleroma/admin/users/:nickname_or_id/statuses`
### Retrive user's latest statuses
@ -300,7 +295,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
}
```
## `GET /api/pleroma/admin/instances/:instance/statuses`
## `GET /api/v1/pleroma/admin/instances/:instance/statuses`
### Retrive instance's latest statuses
@ -324,7 +319,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
}
```
## `GET /api/pleroma/admin/statuses`
## `GET /api/v1/pleroma/admin/statuses`
### Retrives all latest statuses
@ -337,7 +332,7 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- On failure: `Not found`
- On success: JSON array of user's latest statuses
## `GET /api/pleroma/admin/relay`
## `GET /api/v1/pleroma/admin/relay`
### List Relays
@ -353,7 +348,7 @@ Response:
]
```
## `POST /api/pleroma/admin/relay`
## `POST /api/v1/pleroma/admin/relay`
### Follow a Relay
@ -369,7 +364,7 @@ Response:
{"actor": "https://example.com/relay", "followed_back": true}
```
## `DELETE /api/pleroma/admin/relay`
## `DELETE /api/v1/pleroma/admin/relay`
### Unfollow a Relay
@ -385,7 +380,7 @@ Response:
{"https://example.com/relay"}
```
## `POST /api/pleroma/admin/users/invite_token`
## `POST /api/v1/pleroma/admin/users/invite_token`
### Create an account registration invite token
@ -406,7 +401,7 @@ Response:
}
```
## `GET /api/pleroma/admin/users/invites`
## `GET /api/v1/pleroma/admin/users/invites`
### Get a list of generated invites
@ -431,7 +426,7 @@ Response:
}
```
## `POST /api/pleroma/admin/users/revoke_invite`
## `POST /api/v1/pleroma/admin/users/revoke_invite`
### Revoke invite by token
@ -452,7 +447,7 @@ Response:
}
```
## `POST /api/pleroma/admin/users/email_invite`
## `POST /api/v1/pleroma/admin/users/email_invite`
### Sends registration invite via email
@ -473,7 +468,7 @@ Response:
]
```
## `GET /api/pleroma/admin/users/:nickname/password_reset`
## `GET /api/v1/pleroma/admin/users/:nickname/password_reset`
### Get a password reset token for a given nickname
@ -484,11 +479,11 @@ Response:
```json
{
"token": "base64 reset token",
"link": "https://pleroma.social/api/pleroma/password_reset/url-encoded-base64-token"
"link": "https://pleroma.social/api/v1/pleroma/password_reset/url-encoded-base64-token"
}
```
## `PATCH /api/pleroma/admin/users/force_password_reset`
## `PATCH /api/v1/pleroma/admin/users/force_password_reset`
### Force passord reset for a user with a given nickname
@ -496,7 +491,7 @@ Response:
- `nicknames`
- Response: none (code `204`)
## PUT `/api/pleroma/admin/users/disable_mfa`
## PUT `/api/v1/pleroma/admin/users/disable_mfa`
### Disable mfa for user's account.
@ -504,7 +499,7 @@ Response:
- `nickname`
- Response: Users nickname
## `GET /api/pleroma/admin/users/:nickname/credentials`
## `GET /api/v1/pleroma/admin/users/:nickname/credentials`
### Get the user's email, password, display and settings-related fields
@ -552,7 +547,7 @@ Response:
}
```
## `PATCH /api/pleroma/admin/users/:nickname/credentials`
## `PATCH /api/v1/pleroma/admin/users/:nickname/credentials`
### Change the user's email, password, display and settings-related fields
@ -603,7 +598,7 @@ Status: 404
{"error": "Not found"}
```
## `GET /api/pleroma/admin/reports`
## `GET /api/v1/pleroma/admin/reports`
### Get a list of reports
@ -763,17 +758,17 @@ Status: 404
}
```
## `GET /api/pleroma/admin/grouped_reports`
## `GET /api/v1/pleroma/admin/grouped_reports`
### Get a list of reports, grouped by status
- Params: none
- On success: JSON, returns a list of reports, where:
- `date`: date of the latest report
- `account`: the user who has been reported (see `/api/pleroma/admin/reports` for reference)
- `status`: reported status (see `/api/pleroma/admin/reports` for reference)
- `actors`: users who had reported this status (see `/api/pleroma/admin/reports` for reference)
- `reports`: reports (see `/api/pleroma/admin/reports` for reference)
- `account`: the user who has been reported (see `/api/v1/pleroma/admin/reports` for reference)
- `status`: reported status (see `/api/v1/pleroma/admin/reports` for reference)
- `actors`: users who had reported this status (see `/api/v1/pleroma/admin/reports` for reference)
- `reports`: reports (see `/api/v1/pleroma/admin/reports` for reference)
```json
"reports": [
@ -787,7 +782,7 @@ Status: 404
]
```
## `GET /api/pleroma/admin/reports/:id`
## `GET /api/v1/pleroma/admin/reports/:id`
### Get an individual report
@ -799,7 +794,7 @@ Status: 404
- 404 Not Found `"Not found"`
- On success: JSON, Report object (see above)
## `PATCH /api/pleroma/admin/reports`
## `PATCH /api/v1/pleroma/admin/reports`
### Change the state of one or multiple reports
@ -830,7 +825,7 @@ Status: 404
- On success: `204`, empty response
## `POST /api/pleroma/admin/reports/:id/notes`
## `POST /api/v1/pleroma/admin/reports/:id/notes`
### Create report note
@ -842,7 +837,7 @@ Status: 404
- 400 Bad Request `"Invalid parameters"` when `status` is missing
- On success: `204`, empty response
## `DELETE /api/pleroma/admin/reports/:report_id/notes/:id`
## `DELETE /api/v1/pleroma/admin/reports/:report_id/notes/:id`
### Delete report note
@ -854,7 +849,7 @@ Status: 404
- 400 Bad Request `"Invalid parameters"` when `status` is missing
- On success: `204`, empty response
## `GET /api/pleroma/admin/statuses/:id`
## `GET /api/v1/pleroma/admin/statuses/:id`
### Show status by id
@ -865,7 +860,7 @@ Status: 404
- 404 Not Found `"Not Found"`
- On success: JSON, Mastodon Status entity
## `PUT /api/pleroma/admin/statuses/:id`
## `PUT /api/v1/pleroma/admin/statuses/:id`
### Change the scope of an individual reported status
@ -880,7 +875,7 @@ Status: 404
- 404 Not Found `"Not found"`
- On success: JSON, Mastodon Status entity
## `DELETE /api/pleroma/admin/statuses/:id`
## `DELETE /api/v1/pleroma/admin/statuses/:id`
### Delete an individual reported status
@ -892,7 +887,7 @@ Status: 404
- 404 Not Found `"Not found"`
- On success: 200 OK `{}`
## `GET /api/pleroma/admin/restart`
## `GET /api/v1/pleroma/admin/restart`
### Restarts pleroma application
@ -907,7 +902,7 @@ Status: 404
{}
```
## `GET /api/pleroma/admin/need_reboot`
## `GET /api/v1/pleroma/admin/need_reboot`
### Returns the flag whether the pleroma should be restarted
@ -920,7 +915,7 @@ Status: 404
}
```
## `GET /api/pleroma/admin/config`
## `GET /api/v1/pleroma/admin/config`
### Get list of merged default settings with saved in database.
@ -947,7 +942,7 @@ Status: 404
}
```
## `POST /api/pleroma/admin/config`
## `POST /api/v1/pleroma/admin/config`
### Update config settings
@ -1096,7 +1091,7 @@ config :quack,
}
```
## ` GET /api/pleroma/admin/config/descriptions`
## ` GET /api/v1/pleroma/admin/config/descriptions`
### Get JSON with config descriptions.
Loads json generated from `config/descriptions.exs`.
@ -1129,7 +1124,7 @@ Loads json generated from `config/descriptions.exs`.
}]
```
## `GET /api/pleroma/admin/moderation_log`
## `GET /api/v1/pleroma/admin/moderation_log`
### Get moderation log
@ -1159,7 +1154,7 @@ Loads json generated from `config/descriptions.exs`.
]
```
## `POST /api/pleroma/admin/reload_emoji`
## `POST /api/v1/pleroma/admin/reload_emoji`
### Reload the instance's custom emoji
@ -1167,7 +1162,7 @@ Loads json generated from `config/descriptions.exs`.
- Params: None
- Response: JSON, "ok" and 200 status
## `PATCH /api/pleroma/admin/users/confirm_email`
## `PATCH /api/v1/pleroma/admin/users/confirm_email`
### Confirm users' emails
@ -1175,7 +1170,7 @@ Loads json generated from `config/descriptions.exs`.
- `nicknames`
- Response: Array of user nicknames
## `PATCH /api/pleroma/admin/users/resend_confirmation_email`
## `PATCH /api/v1/pleroma/admin/users/resend_confirmation_email`
### Resend confirmation email
@ -1183,13 +1178,13 @@ Loads json generated from `config/descriptions.exs`.
- `nicknames`
- Response: Array of user nicknames
## `GET /api/pleroma/admin/stats`
## `GET /api/v1/pleroma/admin/stats`
### Stats
- Query Params:
- *optional* `instance`: **string** instance hostname (without protocol) to get stats for
- Example: `https://mypleroma.org/api/pleroma/admin/stats?instance=lain.com`
- Example: `https://mypleroma.org/api/v1/pleroma/admin/stats?instance=lain.com`
- Response:
@ -1204,7 +1199,7 @@ Loads json generated from `config/descriptions.exs`.
}
```
## `GET /api/pleroma/admin/oauth_app`
## `GET /api/v1/pleroma/admin/oauth_app`
### List OAuth app
@ -1236,7 +1231,7 @@ Loads json generated from `config/descriptions.exs`.
```
## `POST /api/pleroma/admin/oauth_app`
## `POST /api/v1/pleroma/admin/oauth_app`
### Create OAuth App
@ -1269,7 +1264,7 @@ Loads json generated from `config/descriptions.exs`.
}
```
## `PATCH /api/pleroma/admin/oauth_app/:id`
## `PATCH /api/v1/pleroma/admin/oauth_app/:id`
### Update OAuth App
@ -1294,7 +1289,7 @@ Loads json generated from `config/descriptions.exs`.
}
```
## `DELETE /api/pleroma/admin/oauth_app/:id`
## `DELETE /api/v1/pleroma/admin/oauth_app/:id`
### Delete OAuth App
@ -1305,7 +1300,7 @@ Loads json generated from `config/descriptions.exs`.
- On failure:
- 400 Bad Request `"Invalid parameters"` when `status` is missing
## `GET /api/pleroma/admin/media_proxy_caches`
## `GET /api/v1/pleroma/admin/media_proxy_caches`
### Get a list of all banned MediaProxy URLs in Cachex
@ -1329,7 +1324,7 @@ Loads json generated from `config/descriptions.exs`.
```
## `POST /api/pleroma/admin/media_proxy_caches/delete`
## `POST /api/v1/pleroma/admin/media_proxy_caches/delete`
### Remove a banned MediaProxy URL from Cachex
@ -1344,7 +1339,7 @@ Loads json generated from `config/descriptions.exs`.
```
## `POST /api/pleroma/admin/media_proxy_caches/purge`
## `POST /api/v1/pleroma/admin/media_proxy_caches/purge`
### Purge a MediaProxy URL
@ -1360,7 +1355,7 @@ Loads json generated from `config/descriptions.exs`.
```
## GET /api/pleroma/admin/users/:nickname/chats
## GET /api/v1/pleroma/admin/users/:nickname/chats
### List a user's chats
@ -1389,7 +1384,7 @@ Loads json generated from `config/descriptions.exs`.
]
```
## GET /api/pleroma/admin/chats/:chat_id
## GET /api/v1/pleroma/admin/chats/:chat_id
### View a single chat
@ -1416,7 +1411,7 @@ Loads json generated from `config/descriptions.exs`.
}
```
## GET /api/pleroma/admin/chats/:chat_id/messages
## GET /api/v1/pleroma/admin/chats/:chat_id/messages
### List the messages in a chat
@ -1454,7 +1449,7 @@ Loads json generated from `config/descriptions.exs`.
]
```
## DELETE /api/pleroma/admin/chats/:chat_id/messages/:message_id
## DELETE /api/v1/pleroma/admin/chats/:chat_id/messages/:message_id
### Delete a single message
@ -1481,7 +1476,7 @@ Loads json generated from `config/descriptions.exs`.
}
```
## `GET /api/pleroma/admin/instance_document/:document_name`
## `GET /api/v1/pleroma/admin/instance_document/:document_name`
### Get an instance document
@ -1495,7 +1490,7 @@ Returns the content of the document
<h1>Instance panel</h1>
```
## `PATCH /api/pleroma/admin/instance_document/:document_name`
## `PATCH /api/v1/pleroma/admin/instance_document/:document_name`
- Params:
- `file` (the file to be uploaded, using multipart form data.)
@ -1511,7 +1506,7 @@ Returns the content of the document
}
```
## `DELETE /api/pleroma/admin/instance_document/:document_name`
## `DELETE /api/v1/pleroma/admin/instance_document/:document_name`
### Delete an instance document
@ -1523,7 +1518,7 @@ Returns the content of the document
}
```
## `GET /api/pleroma/admin/frontends
## `GET /api/v1/pleroma/admin/frontends
### List available frontends
@ -1548,7 +1543,7 @@ Returns the content of the document
]
```
## `POST /api/pleroma/admin/frontends/install`
## `POST /api/v1/pleroma/admin/frontends/install`
### Install a frontend

View File

@ -39,6 +39,12 @@ Has these additional fields under the `pleroma` object:
- `emoji_reactions`: A list with emoji / reaction maps. The format is `{name: "☕", count: 1, me: true}`. Contains no information about the reacting users, for that use the `/statuses/:id/reactions` endpoint.
- `parent_visible`: If the parent of this post is visible to the user or not.
## Scheduled statuses
Has these additional fields in `params`:
- `expires_in`: the number of seconds the posted activity should expire in.
## Media Attachments
Has these additional fields under the `pleroma` object:
@ -92,12 +98,12 @@ Has these additional fields under the `pleroma` object:
- `hide_followers_count`: boolean, true when the user has follower stat hiding enabled
- `hide_follows_count`: boolean, true when the user has follow stat hiding enabled
- `settings_store`: A generic map of settings for frontends. Opaque to the backend. Only returned in `/api/v1/accounts/verify_credentials` and `/api/v1/accounts/update_credentials`
- `chat_token`: The token needed for Pleroma chat. Only returned in `/api/v1/accounts/verify_credentials`
- `chat_token`: The token needed for Pleroma shoutbox. Only returned in `/api/v1/accounts/verify_credentials`
- `deactivated`: boolean, true when the user is deactivated
- `allow_following_move`: boolean, true when the user allows automatically follow moved following accounts
- `unread_conversation_count`: The count of unread conversations. Only returned to the account owner.
- `unread_notifications_count`: The count of unread notifications. Only returned to the account owner.
- `notification_settings`: object, can be absent. See `/api/pleroma/notification_settings` for the parameters/keys returned.
- `notification_settings`: object, can be absent. See `/api/v1/pleroma/notification_settings` for the parameters/keys returned.
- `accepts_chat_messages`: boolean, but can be null if we don't have that information about a user
- `favicon`: nullable URL string, Favicon image of the user's instance

View File

@ -4,7 +4,9 @@ Requests that require it can be authenticated with [an OAuth token](https://tool
Request parameters can be passed via [query strings](https://en.wikipedia.org/wiki/Query_string) or as [form data](https://www.w3.org/TR/html401/interact/forms.html). Files must be uploaded as `multipart/form-data`.
## `/api/pleroma/emoji`
The `/api/v1/pleroma/*` path is backwards compatible with `/api/pleroma/*` (`/api/pleroma/*` will be deprecated in the future).
## `/api/v1/pleroma/emoji`
### Lists the custom emoji on that server.
* Method: `GET`
* Authentication: not required
@ -35,7 +37,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
```
* Note: Same data as Mastodon APIs `/api/v1/custom_emojis` but in a different format
## `/api/pleroma/follow_import`
## `/api/v1/pleroma/follow_import`
### Imports your follows, for example from a Mastodon CSV file.
* Method: `POST`
* Authentication: required
@ -44,7 +46,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Response: HTTP 200 on success, 500 on error
* Note: Users that can't be followed are silently skipped.
## `/api/pleroma/blocks_import`
## `/api/v1/pleroma/blocks_import`
### Imports your blocks.
* Method: `POST`
* Authentication: required
@ -52,7 +54,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* `list`: STRING or FILE containing a whitespace-separated list of accounts to block
* Response: HTTP 200 on success, 500 on error
## `/api/pleroma/mutes_import`
## `/api/v1/pleroma/mutes_import`
### Imports your mutes.
* Method: `POST`
* Authentication: required
@ -60,7 +62,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* `list`: STRING or FILE containing a whitespace-separated list of accounts to mute
* Response: HTTP 200 on success, 500 on error
## `/api/pleroma/captcha`
## `/api/v1/pleroma/captcha`
### Get a new captcha
* Method: `GET`
* Authentication: not required
@ -68,7 +70,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Response: Provider specific JSON, the only guaranteed parameter is `type`
* Example response: `{"type": "kocaptcha", "token": "whatever", "url": "https://captcha.kotobank.ch/endpoint", "seconds_valid": 300}`
## `/api/pleroma/delete_account`
## `/api/v1/pleroma/delete_account`
### Delete an account
* Method `POST`
* Authentication: required
@ -77,7 +79,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Response: JSON. Returns `{"status": "success"}` if the deletion was successful, `{"error": "[error message]"}` otherwise
* Example response: `{"error": "Invalid password."}`
## `/api/pleroma/disable_account`
## `/api/v1/pleroma/disable_account`
### Disable an account
* Method `POST`
* Authentication: required
@ -86,21 +88,21 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Response: JSON. Returns `{"status": "success"}` if the account was successfully disabled, `{"error": "[error message]"}` otherwise
* Example response: `{"error": "Invalid password."}`
## `/api/pleroma/accounts/mfa`
## `/api/v1/pleroma/accounts/mfa`
#### Gets current MFA settings
* method: `GET`
* Authentication: required
* OAuth scope: `read:security`
* Response: JSON. Returns `{"enabled": "false", "totp": false }`
## `/api/pleroma/accounts/mfa/setup/totp`
## `/api/v1/pleroma/accounts/mfa/setup/totp`
#### Pre-setup the MFA/TOTP method
* method: `GET`
* Authentication: required
* OAuth scope: `write:security`
* Response: JSON. Returns `{"key": [secret_key], "provisioning_uri": "[qr code uri]" }` when successful, otherwise returns HTTP 422 `{"error": "error_msg"}`
## `/api/pleroma/accounts/mfa/confirm/totp`
## `/api/v1/pleroma/accounts/mfa/confirm/totp`
#### Confirms & enables MFA/TOTP support for user account.
* method: `POST`
* Authentication: required
@ -111,7 +113,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Response: JSON. Returns `{}` if the enable was successful, HTTP 422 `{"error": "[error message]"}` otherwise
## `/api/pleroma/accounts/mfa/totp`
## `/api/v1/pleroma/accounts/mfa/totp`
#### Disables MFA/TOTP method for user account.
* method: `DELETE`
* Authentication: required
@ -121,14 +123,14 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Response: JSON. Returns `{}` if the disable was successful, HTTP 422 `{"error": "[error message]"}` otherwise
* Example response: `{"error": "Invalid password."}`
## `/api/pleroma/accounts/mfa/backup_codes`
## `/api/v1/pleroma/accounts/mfa/backup_codes`
#### Generstes backup codes MFA for user account.
* method: `GET`
* Authentication: required
* OAuth scope: `write:security`
* Response: JSON. Returns `{"codes": codes}`when successful, otherwise HTTP 422 `{"error": "[error message]"}`
## `/api/pleroma/admin/`
## `/api/v1/pleroma/admin/`
See [Admin-API](admin_api.md)
## `/api/v1/pleroma/notifications/read`
@ -298,7 +300,7 @@ See [Admin-API](admin_api.md)
* Note: Behaves exactly the same as `POST /api/v1/upload`.
Can only accept images - any attempt to upload non-image files will be met with `HTTP 415 Unsupported Media Type`.
## `/api/pleroma/notification_settings`
## `/api/v1/pleroma/notification_settings`
### Updates user notification settings
* Method `PUT`
* Authentication: required
@ -307,7 +309,7 @@ See [Admin-API](admin_api.md)
* `hide_notification_contents`: BOOLEAN field. When set to true, it removes the contents of a message from the push notification.
* Response: JSON. Returns `{"status": "success"}` if the update was successful, otherwise returns `{"error": "error_msg"}`
## `/api/pleroma/healthcheck`
## `/api/v1/pleroma/healthcheck`
### Healthcheck endpoint with additional system data.
* Method `GET`
* Authentication: not required
@ -325,7 +327,7 @@ See [Admin-API](admin_api.md)
}
```
## `/api/pleroma/change_email`
## `/api/v1/pleroma/change_email`
### Change account email
* Method `POST`
* Authentication: required
@ -378,7 +380,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Params: None
* Response: JSON, returns a list of Mastodon Conversation entities that were marked as read (200 - healthy, 503 unhealthy).
## `GET /api/pleroma/emoji/pack?name=:name`
## `GET /api/v1/pleroma/emoji/pack?name=:name`
### Get pack.json for the pack
@ -397,7 +399,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
}
```
## `POST /api/pleroma/emoji/pack?name=:name`
## `POST /api/v1/pleroma/emoji/pack?name=:name`
### Creates an empty pack
@ -407,7 +409,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* `name`: pack name
* Response: JSON, "ok" and 200 status or 409 if the pack with that name already exists
## `PATCH /api/pleroma/emoji/pack?name=:name`
## `PATCH /api/v1/pleroma/emoji/pack?name=:name`
### Updates (replaces) pack metadata
@ -425,7 +427,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Response: JSON, updated "metadata" section of the pack and 200 status or 400 if there was a
problem with the new metadata (the error is specified in the "error" part of the response JSON)
## `DELETE /api/pleroma/emoji/pack?name=:name`
## `DELETE /api/v1/pleroma/emoji/pack?name=:name`
### Delete a custom emoji pack
@ -435,7 +437,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* `name`: pack name
* Response: JSON, "ok" and 200 status or 500 if there was an error deleting the pack
## `GET /api/pleroma/emoji/packs/import`
## `GET /api/v1/pleroma/emoji/packs/import`
### Imports packs from filesystem
@ -444,7 +446,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Params: None
* Response: JSON, returns a list of imported packs.
## `GET /api/pleroma/emoji/packs/remote`
## `GET /api/v1/pleroma/emoji/packs/remote`
### Make request to another instance for packs list
@ -456,7 +458,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* `page_size`: page size for packs (default 50)
* Response: JSON with the pack list, hashmap with pack name and pack contents
## `POST /api/pleroma/emoji/packs/download`
## `POST /api/v1/pleroma/emoji/packs/download`
### Download pack from another instance
@ -469,7 +471,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Response: JSON, "ok" with 200 status if the pack was downloaded, or 500 if there were
errors downloading the pack
## `POST /api/pleroma/emoji/packs/files?name=:name`
## `POST /api/v1/pleroma/emoji/packs/files?name=:name`
### Add new file to the pack
@ -482,7 +484,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* `filename`: (*optional*) new emoji file name. If not specified will be taken from original filename.
* Response: JSON, list of files for updated pack (hashmap -> shortcode => filename) with status 200, either error status with error message.
## `PATCH /api/pleroma/emoji/packs/files?name=:name`
## `PATCH /api/v1/pleroma/emoji/packs/files?name=:name`
### Update emoji file from pack
@ -496,7 +498,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* `force`: (*optional*) with true value to overwrite existing emoji with new shortcode
* Response: JSON, list with updated files for updated pack (hashmap -> shortcode => filename) with status 200, either error status with error message.
## `DELETE /api/pleroma/emoji/packs/files?name=:name`
## `DELETE /api/v1/pleroma/emoji/packs/files?name=:name`
### Delete emoji file from pack
@ -507,7 +509,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* `shortcode`: emoji file shortcode
* Response: JSON, list with updated files for updated pack (hashmap -> shortcode => filename) with status 200, either error status with error message.
## `GET /api/pleroma/emoji/packs`
## `GET /api/v1/pleroma/emoji/packs`
### Lists local custom emoji packs
@ -528,7 +530,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
}
```
## `GET /api/pleroma/emoji/packs/archive?name=:name`
## `GET /api/v1/pleroma/emoji/packs/archive?name=:name`
### Requests a local pack archive from the instance

View File

@ -150,7 +150,7 @@ su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
# su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate --migrations-path priv/repo/optional_migrations/rum_indexing/"
# Start the instance to verify that everything is working as expected
su pleroma -s $SHELL -lc "export $(cat /opt/pleroma/config/pleroma.env); ./bin/pleroma daemon"
su pleroma -s $SHELL -lc "./bin/pleroma daemon"
# Wait for about 20 seconds and query the instance endpoint, if it shows your uri, name and email correctly, you are configured correctly
sleep 20 && curl http://localhost:4000/api/v1/instance

View File

@ -20,7 +20,8 @@ defmodule Mix.Tasks.Pleroma.Ecto.Rollback do
start: :boolean,
quiet: :boolean,
log_sql: :boolean,
migrations_path: :string
migrations_path: :string,
env: :string
]
@moduledoc """
@ -59,7 +60,7 @@ defmodule Mix.Tasks.Pleroma.Ecto.Rollback do
level = Logger.level()
Logger.configure(level: :info)
if Pleroma.Config.get(:env) == :test do
if opts[:env] == "test" do
Logger.info("Rollback succesfully")
else
{:ok, _, _} =

View File

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

View File

@ -97,13 +97,13 @@ defmodule Pleroma.Application do
Pleroma.Stats,
Pleroma.JobQueueMonitor,
{Majic.Pool, [name: Pleroma.MajicPool, pool_size: Config.get([:majic_pool, :size], 2)]},
{Oban, Config.get(Oban)}
{Oban, Config.get(Oban)},
Pleroma.Web.Endpoint
] ++
task_children(@mix_env) ++
dont_run_in_test(@mix_env) ++
chat_child(chat_enabled?()) ++
[
Pleroma.Web.Endpoint,
Pleroma.Gopher.Server
]

View File

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

View File

@ -18,7 +18,8 @@ defmodule Pleroma.Constants do
"emoji",
"context_id",
"deleted_activity_id",
"pleroma_internal"
"pleroma_internal",
"generator"
]
)

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
defmodule Pleroma.ReverseProxy do
@range_headers ~w(range if-range)
@keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since) ++
@keep_req_headers ~w(accept accept-encoding cache-control if-modified-since) ++
~w(if-unmodified-since if-none-match) ++ @range_headers
@resp_cache_headers ~w(etag date last-modified)
@keep_resp_headers @resp_cache_headers ++
@ -57,9 +57,6 @@ defmodule Pleroma.ReverseProxy do
* `false` will add `content-disposition: attachment` to any request,
* a list of whitelisted content types
* `keep_user_agent` will forward the client's user-agent to the upstream. This may be useful if the upstream is
doing content transformation (encoding, ) depending on the request.
* `req_headers`, `resp_headers` additional headers.
* `http`: options for [hackney](https://github.com/benoitc/hackney) or [gun](https://github.com/ninenines/gun).
@ -84,8 +81,7 @@ defmodule Pleroma.ReverseProxy do
import Plug.Conn
@type option() ::
{:keep_user_agent, boolean}
| {:max_read_duration, :timer.time() | :infinity}
{:max_read_duration, :timer.time() | :infinity}
| {:max_body_length, non_neg_integer() | :infinity}
| {:failed_request_ttl, :timer.time() | :infinity}
| {:http, []}
@ -291,17 +287,13 @@ defmodule Pleroma.ReverseProxy do
end
end
defp build_req_user_agent_header(headers, opts) do
if Keyword.get(opts, :keep_user_agent, false) do
List.keystore(
headers,
"user-agent",
0,
{"user-agent", Pleroma.Application.user_agent()}
)
else
headers
end
defp build_req_user_agent_header(headers, _opts) do
List.keystore(
headers,
"user-agent",
0,
{"user-agent", Pleroma.Application.user_agent()}
)
end
defp build_resp_headers(headers, opts) do

View File

@ -23,7 +23,11 @@ defmodule Pleroma.Stats do
@impl true
def init(_args) do
{:ok, nil, {:continue, :calculate_stats}}
if Pleroma.Config.get(:env) != :test do
{:ok, nil, {:continue, :calculate_stats}}
else
{:ok, calculate_stat_data()}
end
end
@doc "Performs update stats"

View File

@ -11,7 +11,8 @@ defmodule Pleroma.Upload.Filter.Exiftool do
@spec filter(Pleroma.Upload.t()) :: {:ok, any()} | {:error, String.t()}
# webp is not compatible with exiftool at this time
# Formats not compatible with exiftool at this time
def filter(%Pleroma.Upload{content_type: "image/heic"}), do: {:ok, :noop}
def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
@ -21,8 +22,8 @@ defmodule Pleroma.Upload.Filter.Exiftool do
{error, 1} -> {:error, error}
end
rescue
_e in ErlangError ->
{:error, "exiftool command not found"}
e in ErlangError ->
{:error, "#{__MODULE__}: #{inspect(e)}"}
end
end

View File

@ -44,8 +44,8 @@ defmodule Pleroma.Upload.Filter.Mogrifun do
Filter.Mogrify.do_filter(file, [Enum.random(@filters)])
{:ok, :filtered}
rescue
_e in ErlangError ->
{:error, "mogrify command not found"}
e in ErlangError ->
{:error, "#{__MODULE__}: #{inspect(e)}"}
end
end

View File

@ -14,8 +14,8 @@ defmodule Pleroma.Upload.Filter.Mogrify do
do_filter(file, Pleroma.Config.get!([__MODULE__, :args]))
{:ok, :filtered}
rescue
_e in ErlangError ->
{:error, "mogrify command not found"}
e in ErlangError ->
{:error, "#{__MODULE__}: #{inspect(e)}"}
end
end

View File

@ -147,6 +147,7 @@ defmodule Pleroma.User do
field(:shared_inbox, :string)
field(:accepts_chat_messages, :boolean, default: nil)
field(:last_active_at, :naive_datetime)
field(:disclose_client, :boolean, default: true)
embeds_one(
:notification_settings,
@ -513,7 +514,8 @@ defmodule Pleroma.User do
:pleroma_settings_store,
:is_discoverable,
:actor_type,
:accepts_chat_messages
:accepts_chat_messages,
:disclose_client
]
)
|> unique_constraint(:nickname)

View File

@ -63,7 +63,8 @@ defmodule Pleroma.Web do
# Executed just before actual controller action, invokes before-action hooks (callbacks)
defp action(conn, params) do
with %{halted: false} = conn <- maybe_drop_authentication_if_oauth_check_ignored(conn),
with %{halted: false} = conn <-
maybe_drop_authentication_if_oauth_check_ignored(conn),
%{halted: false} = conn <- maybe_perform_public_or_authenticated_check(conn),
%{halted: false} = conn <- maybe_perform_authenticated_check(conn),
%{halted: false} = conn <- maybe_halt_on_missing_oauth_scopes_check(conn) do
@ -232,4 +233,16 @@ defmodule Pleroma.Web do
def base_url do
Pleroma.Web.Endpoint.url()
end
# TODO: Change to Phoenix.Router.routes/1 for Phoenix 1.6.0+
def get_api_routes do
Pleroma.Web.Router.__routes__()
|> Enum.reject(fn r -> r.plug == Pleroma.Web.Fallback.RedirectController end)
|> Enum.map(fn r ->
r.path
|> String.split("/", trim: true)
|> List.first()
end)
|> Enum.uniq()
end
end

View File

@ -70,19 +70,33 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do
|> changeset(data)
end
defp fix_url(%{"url" => url} = data) when is_list(url) do
attachment =
Enum.find(url, fn x ->
mime_type = x["mimeType"] || x["mediaType"] || ""
defp find_attachment(url) do
mpeg_url =
Enum.find(url, fn
%{"mediaType" => mime_type, "tag" => tags} when is_list(tags) ->
mime_type == "application/x-mpegURL"
is_map(x) and String.starts_with?(mime_type, ["video/", "audio/"])
_ ->
false
end)
link_element =
Enum.find(url, fn x ->
mime_type = x["mimeType"] || x["mediaType"] || ""
url
|> Enum.concat(mpeg_url["tag"] || [])
|> Enum.find(fn
%{"mediaType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"])
%{"mimeType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"])
_ -> false
end)
end
is_map(x) and mime_type == "text/html"
defp fix_url(%{"url" => url} = data) when is_list(url) do
attachment = find_attachment(url)
link_element =
Enum.find(url, fn
%{"mediaType" => "text/html"} -> true
%{"mimeType" => "text/html"} -> true
_ -> false
end)
data

View File

@ -25,13 +25,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug(
OAuthScopesPlug,
%{scopes: ["read:accounts"], admin: true}
%{scopes: ["admin:read:accounts"]}
when action in [:right_get, :show_user_credentials, :create_backup]
)
plug(
OAuthScopesPlug,
%{scopes: ["write:accounts"], admin: true}
%{scopes: ["admin:write:accounts"]}
when action in [
:get_password_reset,
:force_password_reset,
@ -48,19 +48,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug(
OAuthScopesPlug,
%{scopes: ["read:statuses"], admin: true}
%{scopes: ["admin:read:statuses"]}
when action in [:list_user_statuses, :list_instance_statuses]
)
plug(
OAuthScopesPlug,
%{scopes: ["read:chats"], admin: true}
%{scopes: ["admin:read:chats"]}
when action in [:list_user_chats]
)
plug(
OAuthScopesPlug,
%{scopes: ["read"], admin: true}
%{scopes: ["admin:read"]}
when action in [
:list_log,
:stats,
@ -70,7 +70,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug(
OAuthScopesPlug,
%{scopes: ["write"], admin: true}
%{scopes: ["admin:write"]}
when action in [
:restart,
:resend_confirmation_email,

View File

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

View File

@ -10,11 +10,11 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :update)
plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :update)
plug(
OAuthScopesPlug,
%{scopes: ["read"], admin: true}
%{scopes: ["admin:read"]}
when action in [:show, :descriptions]
)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,13 +21,13 @@ defmodule Pleroma.Web.AdminAPI.UserController do
plug(
OAuthScopesPlug,
%{scopes: ["read:accounts"], admin: true}
%{scopes: ["admin:read:accounts"]}
when action in [:list, :show]
)
plug(
OAuthScopesPlug,
%{scopes: ["write:accounts"], admin: true}
%{scopes: ["admin:write:accounts"]}
when action in [
:delete,
:create,
@ -40,7 +40,7 @@ defmodule Pleroma.Web.AdminAPI.UserController do
plug(
OAuthScopesPlug,
%{scopes: ["write:follows"], admin: true}
%{scopes: ["admin:write:follows"]}
when action in [:follow, :unfollow]
)

View File

@ -37,7 +37,8 @@ defmodule Pleroma.Web.ApiSpec do
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(),
# Strip environment from the version
version: Application.spec(:pleroma, :vsn) |> to_string() |> String.replace(~r/\+.*$/, ""),
extensions: %{
# Logo path should be picked so that the path exists both on Pleroma instances and on api.pleroma.social
"x-logo": %{"url" => "/static/logo.svg", "altText" => "Pleroma logo"}
@ -84,7 +85,7 @@ defmodule Pleroma.Web.ApiSpec do
"name" => "Administration",
"tags" => [
"Chat administration",
"Emoji packs",
"Emoji pack administration",
"Frontend managment",
"Instance configuration",
"Instance documents",
@ -126,7 +127,7 @@ defmodule Pleroma.Web.ApiSpec do
"Status actions"
]
},
%{"name" => "Miscellaneous", "tags" => ["Reports", "Suggestions"]}
%{"name" => "Miscellaneous", "tags" => ["Emoji packs", "Reports", "Suggestions"]}
]
}
}

View File

@ -33,7 +33,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
},
security: [
%{
"oAuth" => ["write:chats"]
"oAuth" => ["admin:write:chats"]
}
]
}
@ -57,7 +57,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
},
security: [
%{
"oAuth" => ["read:chats"]
"oAuth" => ["admin:read:chats"]
}
]
}
@ -88,7 +88,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
},
security: [
%{
"oAuth" => ["read"]
"oAuth" => ["admin:read"]
}
]
}

View File

@ -28,7 +28,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
)
| admin_api_params()
],
security: [%{"oAuth" => ["read"]}],
security: [%{"oAuth" => ["admin:read"]}],
responses: %{
200 => Operation.response("Config", "application/json", config_response()),
400 => Operation.response("Bad Request", "application/json", ApiError)
@ -41,7 +41,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
tags: ["Instance configuration"],
summary: "Update instance configuration",
operationId: "AdminAPI.ConfigController.update",
security: [%{"oAuth" => ["write"]}],
security: [%{"oAuth" => ["admin:write"]}],
parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
tags: ["Instance configuration"],
summary: "Retrieve config description",
operationId: "AdminAPI.ConfigController.descriptions",
security: [%{"oAuth" => ["read"]}],
security: [%{"oAuth" => ["admin:read"]}],
parameters: admin_api_params(),
responses: %{
200 =>

View File

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

View File

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

View File

@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Get a list of generated invites",
operationId: "AdminAPI.InviteController.index",
security: [%{"oAuth" => ["read:invites"]}],
security: [%{"oAuth" => ["admin:read:invites"]}],
parameters: admin_api_params(),
responses: %{
200 =>
@ -51,7 +51,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Create an account registration invite token",
operationId: "AdminAPI.InviteController.create",
security: [%{"oAuth" => ["write:invites"]}],
security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
@ -72,7 +72,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Revoke invite by token",
operationId: "AdminAPI.InviteController.revoke",
security: [%{"oAuth" => ["write:invites"]}],
security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(),
requestBody:
request_body(
@ -99,7 +99,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Sends registration invite via email",
operationId: "AdminAPI.InviteController.email",
security: [%{"oAuth" => ["write:invites"]}],
security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(),
requestBody:
request_body(

View File

@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
tags: ["MediaProxy cache"],
summary: "Retrieve a list of banned MediaProxy URLs",
operationId: "AdminAPI.MediaProxyCacheController.index",
security: [%{"oAuth" => ["read:media_proxy_caches"]}],
security: [%{"oAuth" => ["admin:read:media_proxy_caches"]}],
parameters: [
Operation.parameter(
:query,
@ -71,7 +71,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
tags: ["MediaProxy cache"],
summary: "Remove a banned MediaProxy URL",
operationId: "AdminAPI.MediaProxyCacheController.delete",
security: [%{"oAuth" => ["write:media_proxy_caches"]}],
security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
parameters: admin_api_params(),
requestBody:
request_body(
@ -97,7 +97,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
tags: ["MediaProxy cache"],
summary: "Purge a URL from MediaProxy cache and optionally ban it",
operationId: "AdminAPI.MediaProxyCacheController.purge",
security: [%{"oAuth" => ["write:media_proxy_caches"]}],
security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
parameters: admin_api_params(),
requestBody:
request_body(

View File

@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
summary: "Retrieve a list of OAuth applications",
tags: ["OAuth application managment"],
operationId: "AdminAPI.OAuthAppController.index",
security: [%{"oAuth" => ["write"]}],
security: [%{"oAuth" => ["admin:write"]}],
parameters: [
Operation.parameter(:name, :query, %Schema{type: :string}, "App name"),
Operation.parameter(:client_id, :query, %Schema{type: :string}, "Client ID"),
@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
operationId: "AdminAPI.OAuthAppController.create",
requestBody: request_body("Parameters", create_request()),
parameters: admin_api_params(),
security: [%{"oAuth" => ["write"]}],
security: [%{"oAuth" => ["admin:write"]}],
responses: %{
200 => Operation.response("App", "application/json", oauth_app()),
400 => Operation.response("Bad Request", "application/json", ApiError)
@ -88,7 +88,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
summary: "Update OAuth application",
operationId: "AdminAPI.OAuthAppController.update",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}],
security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", update_request()),
responses: %{
200 => Operation.response("App", "application/json", oauth_app()),
@ -106,7 +106,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
summary: "Delete OAuth application",
operationId: "AdminAPI.OAuthAppController.delete",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}],
security: [%{"oAuth" => ["admin:write"]}],
responses: %{
204 => no_content_response(),
400 => no_content_response()

View File

@ -18,7 +18,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
tags: ["Relays"],
summary: "Retrieve a list of relays",
operationId: "AdminAPI.RelayController.index",
security: [%{"oAuth" => ["read"]}],
security: [%{"oAuth" => ["admin:read"]}],
parameters: admin_api_params(),
responses: %{
200 =>
@ -40,7 +40,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
tags: ["Relays"],
summary: "Follow a relay",
operationId: "AdminAPI.RelayController.follow",
security: [%{"oAuth" => ["write:follows"]}],
security: [%{"oAuth" => ["admin:write:follows"]}],
parameters: admin_api_params(),
requestBody: request_body("Parameters", relay_url()),
responses: %{
@ -54,7 +54,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
tags: ["Relays"],
summary: "Unfollow a relay",
operationId: "AdminAPI.RelayController.unfollow",
security: [%{"oAuth" => ["write:follows"]}],
security: [%{"oAuth" => ["admin:write:follows"]}],
parameters: admin_api_params(),
requestBody: request_body("Parameters", relay_unfollow()),
responses: %{

View File

@ -22,7 +22,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
tags: ["Report managment"],
summary: "Retrieve a list of reports",
operationId: "AdminAPI.ReportController.index",
security: [%{"oAuth" => ["read:reports"]}],
security: [%{"oAuth" => ["admin:read:reports"]}],
parameters: [
Operation.parameter(
:state,
@ -73,7 +73,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
summary: "Retrieve a report",
operationId: "AdminAPI.ReportController.show",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:reports"]}],
security: [%{"oAuth" => ["admin:read:reports"]}],
responses: %{
200 => Operation.response("Report", "application/json", report()),
404 => Operation.response("Not Found", "application/json", ApiError)
@ -86,7 +86,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
tags: ["Report managment"],
summary: "Change state of specified reports",
operationId: "AdminAPI.ReportController.update",
security: [%{"oAuth" => ["write:reports"]}],
security: [%{"oAuth" => ["admin:write:reports"]}],
parameters: admin_api_params(),
requestBody: request_body("Parameters", update_request(), required: true),
responses: %{
@ -110,7 +110,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
content: %Schema{type: :string, description: "The message"}
}
}),
security: [%{"oAuth" => ["write:reports"]}],
security: [%{"oAuth" => ["admin:write:reports"]}],
responses: %{
204 => no_content_response(),
404 => Operation.response("Not Found", "application/json", ApiError)
@ -128,7 +128,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
Operation.parameter(:id, :path, :string, "Note ID")
| admin_api_params()
],
security: [%{"oAuth" => ["write:reports"]}],
security: [%{"oAuth" => ["admin:write:reports"]}],
responses: %{
204 => no_content_response(),
404 => Operation.response("Not Found", "application/json", ApiError)
@ -136,11 +136,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
}
end
defp report_state do
def report_state do
%Schema{type: :string, enum: ["open", "closed", "resolved"]}
end
defp id_param do
def id_param do
Operation.parameter(:id, :path, FlakeID, "Report ID",
example: "9umDrYheeY451cQnEe",
required: true

View File

@ -24,7 +24,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
tags: ["Status administration"],
operationId: "AdminAPI.StatusController.index",
summary: "Get all statuses",
security: [%{"oAuth" => ["read:statuses"]}],
security: [%{"oAuth" => ["admin:read:statuses"]}],
parameters: [
Operation.parameter(
:godmode,
@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
summary: "Get status",
operationId: "AdminAPI.StatusController.show",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:statuses"]}],
security: [%{"oAuth" => ["admin:read:statuses"]}],
responses: %{
200 => Operation.response("Status", "application/json", status()),
404 => Operation.response("Not Found", "application/json", ApiError)
@ -88,7 +88,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
summary: "Change the scope of a status",
operationId: "AdminAPI.StatusController.update",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}],
security: [%{"oAuth" => ["admin:write:statuses"]}],
requestBody: request_body("Parameters", update_request(), required: true),
responses: %{
200 => Operation.response("Status", "application/json", Status),
@ -103,7 +103,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
summary: "Delete status",
operationId: "AdminAPI.StatusController.delete",
parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}],
security: [%{"oAuth" => ["admin:write:statuses"]}],
responses: %{
200 => empty_object_response(),
404 => Operation.response("Not Found", "application/json", ApiError)

View File

@ -131,8 +131,30 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def index_operation do
%Operation{
tags: ["Chats"],
summary: "Retrieve list of chats",
summary: "Retrieve list of chats (unpaginated)",
deprecated: true,
description:
"Deprecated due to no support for pagination. Using [/api/v2/pleroma/chats](#operation/ChatController.index2) instead is recommended.",
operationId: "ChatController.index",
parameters: [
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
],
responses: %{
200 => Operation.response("The chats of the user", "application/json", chats_response())
},
security: [
%{
"oAuth" => ["read:chats"]
}
]
}
end
def index2_operation do
%Operation{
tags: ["Chats"],
summary: "Retrieve list of chats",
operationId: "ChatController.index2",
parameters: [
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
| pagination_params()

View File

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

View File

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

View File

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

View File

@ -0,0 +1,97 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.PleromaReportOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Admin.ReportOperation
alias Pleroma.Web.ApiSpec.Schemas.Account
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
alias Pleroma.Web.ApiSpec.Schemas.Status
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def index_operation do
%Operation{
tags: ["Reports"],
summary: "Get a list of your own reports",
operationId: "PleromaAPI.ReportController.index",
security: [%{"oAuth" => ["read:reports"]}],
parameters: [
Operation.parameter(
:state,
:query,
ReportOperation.report_state(),
"Filter by report state"
),
Operation.parameter(
:limit,
:query,
%Schema{type: :integer},
"The number of records to retrieve"
),
Operation.parameter(
:page,
:query,
%Schema{type: :integer, default: 1},
"Page number"
),
Operation.parameter(
:page_size,
:query,
%Schema{type: :integer, default: 50},
"Number number of log entries per page"
)
],
responses: %{
200 =>
Operation.response("Response", "application/json", %Schema{
type: :object,
properties: %{
total: %Schema{type: :integer},
reports: %Schema{
type: :array,
items: report()
}
}
}),
404 => Operation.response("Not Found", "application/json", ApiError)
}
}
end
def show_operation do
%Operation{
tags: ["Reports"],
summary: "Get an individual report",
operationId: "PleromaAPI.ReportController.show",
parameters: [ReportOperation.id_param()],
security: [%{"oAuth" => ["read:reports"]}],
responses: %{
200 => Operation.response("Report", "application/json", report()),
404 => Operation.response("Not Found", "application/json", ApiError)
}
}
end
# Copied from ReportOperation.report with removing notes
defp report do
%Schema{
type: :object,
properties: %{
id: FlakeID,
state: ReportOperation.report_state(),
account: Account,
actor: Account,
content: %Schema{type: :string},
created_at: %Schema{type: :string, format: :"date-time"},
statuses: %Schema{type: :array, items: Status}
}
}
end
end

View File

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

View File

@ -30,7 +30,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
visibility: %Schema{allOf: [VisibilityScope], nullable: true},
scheduled_at: %Schema{type: :string, format: :"date-time", nullable: true},
poll: StatusOperation.poll_params(),
in_reply_to_id: %Schema{type: :string, nullable: true}
in_reply_to_id: %Schema{type: :string, nullable: true},
expires_in: %Schema{type: :integer, nullable: true}
}
}
},
@ -46,7 +47,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
scheduled_at: nil,
poll: nil,
idempotency: nil,
in_reply_to_id: nil
in_reply_to_id: nil,
expires_in: nil
},
media_attachments: [Attachment.schema().example]
}

View File

@ -23,9 +23,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
application: %Schema{
description: "The application used to post this status",
type: :object,
nullable: true,
properties: %{
name: %Schema{type: :string},
website: %Schema{type: :string, nullable: true, format: :uri}
website: %Schema{type: :string, format: :uri}
}
},
bookmarked: %Schema{type: :boolean, description: "Have you bookmarked this status?"},
@ -291,7 +292,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
"url" => "http://localhost:4001/users/nick6",
"username" => "nick6"
},
"application" => %{"name" => "Web", "website" => nil},
"application" => nil,
"bookmarked" => false,
"card" => nil,
"content" => "foobar",

View File

@ -190,6 +190,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
Utils.make_note_data(draft)
|> Map.put("emoji", emoji)
|> Map.put("source", draft.status)
|> Map.put("generator", draft.params[:generator])
%__MODULE__{draft | object: object}
end

View File

@ -0,0 +1,26 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Fallback.LegacyPleromaApiRerouterPlug do
alias Pleroma.Web.Endpoint
alias Pleroma.Web.Fallback.RedirectController
def init(opts), do: opts
def call(%{path_info: ["api", "pleroma" | path_info_rest]} = conn, _opts) do
new_path_info = ["api", "v1", "pleroma" | path_info_rest]
new_request_path = Enum.join(new_path_info, "/")
conn
|> Map.merge(%{
path_info: new_path_info,
request_path: new_request_path
})
|> Endpoint.call(conn.params)
end
def call(conn, _opts) do
RedirectController.api_not_implemented(conn, %{})
end
end

View File

@ -3,6 +3,11 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.AppController do
@moduledoc """
Controller for supporting app-related actions.
If authentication is an option, app tokens (user-unbound) must be supported.
"""
use Pleroma.Web, :controller
alias Pleroma.Repo
@ -17,11 +22,9 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
plug(
:skip_plug,
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug]
when action == :create
when action in [:create, :verify_credentials]
)
plug(OAuthScopesPlug, %{scopes: ["read"]} when action == :verify_credentials)
plug(Pleroma.Web.ApiSpec.CastAndValidate)
@local_mastodon_name "Mastodon-Local"
@ -44,10 +47,13 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
end
end
@doc "GET /api/v1/apps/verify_credentials"
def verify_credentials(%{assigns: %{user: _user, token: token}} = conn, _) do
with %Token{app: %App{} = app} <- Repo.preload(token, :app) do
render(conn, "short.json", app: app)
@doc """
GET /api/v1/apps/verify_credentials
Gets compact non-secret representation of the app. Supports app tokens and user tokens.
"""
def verify_credentials(%{assigns: %{token: %Token{} = token}} = conn, _) do
with %{app: %App{} = app} <- Repo.preload(token, :app) do
render(conn, "compact_non_secret.json", app: app)
end
end
end

View File

@ -36,4 +36,13 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
render(conn, "participation.json", participation: participation, for: user)
end
end
@doc "DELETE /api/v1/conversations/:id"
def delete(%{assigns: %{user: user}} = conn, %{id: participation_id}) do
with %Participation{} = participation <-
Repo.get_by(Participation, id: participation_id, user_id: user.id),
{:ok, _} <- Participation.delete(participation) do
json(conn, %{})
end
end
end

View File

@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.Plugs.RateLimiter
@ -138,7 +139,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
_
)
when not is_nil(scheduled_at) do
params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
params =
Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
|> put_application(conn)
attrs = %{
params: Map.new(params, fn {key, value} -> {to_string(key), value} end),
@ -162,7 +165,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
# Creates a regular status
def create(%{assigns: %{user: user}, body_params: %{status: _} = params} = conn, _) do
params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
params =
Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
|> put_application(conn)
with {:ok, activity} <- CommonAPI.post(user, params) do
try_render(conn, "show.json",
@ -414,4 +419,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
as: :activity
)
end
defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do
if user.disclose_client do
%{client_name: client_name, website: website} = Repo.preload(token, :app).app
Map.put(params, :generator, %{type: "Application", name: client_name, url: website})
else
Map.put(params, :generator, nil)
end
end
defp put_application(params, _), do: Map.put(params, :generator, nil)
end

View File

@ -34,10 +34,10 @@ defmodule Pleroma.Web.MastodonAPI.AppView do
|> with_vapid_key()
end
def render("short.json", %{app: %App{website: webiste, client_name: name}}) do
def render("compact_non_secret.json", %{app: %App{website: website, client_name: name}}) do
%{
name: name,
website: webiste
website: website
}
|> with_vapid_key()
end

View File

@ -37,7 +37,8 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do
visibility: params["visibility"],
scheduled_at: params["scheduled_at"],
poll: params["poll"],
in_reply_to_id: params["in_reply_to_id"]
in_reply_to_id: params["in_reply_to_id"],
expires_in: params["expires_in"]
}
|> Pleroma.Maps.put_if_present(:media_ids, params["media_ids"])
end

View File

@ -124,16 +124,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
) do
user = CommonAPI.get_user(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"])
activity_object = Object.normalize(activity, fetch: false)
object = Object.normalize(activity, fetch: false)
reblogged_parent_activity =
if opts[:parent_activities] do
Activity.Queries.find_by_object_ap_id(
opts[:parent_activities],
activity_object.data["id"]
object.data["id"]
)
else
Activity.create_by_object_ap_id(activity_object.data["id"])
Activity.create_by_object_ap_id(object.data["id"])
|> Activity.with_preloaded_bookmark(opts[:for])
|> Activity.with_set_thread_muted_field(opts[:for])
|> Repo.one()
@ -142,7 +142,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
reblog_rendering_opts = Map.put(opts, :activity, reblogged_parent_activity)
reblogged = render("show.json", reblog_rendering_opts)
favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || [])
favorited = opts[:for] && opts[:for].ap_id in (object.data["likes"] || [])
bookmarked = Activity.get_bookmark(reblogged_parent_activity, opts[:for]) != nil
@ -154,8 +154,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
%{
id: to_string(activity.id),
uri: activity_object.data["id"],
url: activity_object.data["id"],
uri: object.data["id"],
url: object.data["id"],
account:
AccountView.render("show.json", %{
user: user,
@ -180,10 +180,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
media_attachments: reblogged[:media_attachments] || [],
mentions: mentions,
tags: reblogged[:tags] || [],
application: %{
name: "Web",
website: nil
},
application: build_application(object.data["generator"]),
language: nil,
emojis: [],
pleroma: %{
@ -348,10 +345,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
poll: render(PollView, "show.json", object: object, for: opts[:for]),
mentions: mentions,
tags: build_tags(tags),
application: %{
name: "Web",
website: nil
},
application: build_application(object.data["generator"]),
language: nil,
emojis: build_emojis(object.data["emoji"]),
pleroma: %{
@ -540,4 +534,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
me: !!(current_user && current_user.ap_id in users)
}
end
@spec build_application(map() | nil) :: map() | nil
defp build_application(%{"type" => _type, "name" => name, "url" => url}),
do: %{name: name, website: url}
defp build_application(_), do: nil
end

View File

@ -35,7 +35,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
plug(
OAuthScopesPlug,
%{scopes: ["read:chats"]} when action in [:messages, :index, :show]
%{scopes: ["read:chats"]} when action in [:messages, :index, :index2, :show]
)
plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
@ -138,18 +138,30 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
end
end
def index(%{assigns: %{user: %{id: user_id} = user}} = conn, params) do
def index(%{assigns: %{user: user}} = conn, params) do
chats =
index_query(user, params)
|> Repo.all()
render(conn, "index.json", chats: chats)
end
def index2(%{assigns: %{user: user}} = conn, params) do
chats =
index_query(user, params)
|> Pagination.fetch_paginated(params)
render(conn, "index.json", chats: chats)
end
defp index_query(%{id: user_id} = user, params) do
exclude_users =
User.cached_blocked_users_ap_ids(user) ++
if params[:with_muted], do: [], else: User.cached_muted_users_ap_ids(user)
chats =
user_id
|> Chat.for_user_query()
|> where([c], c.recipient not in ^exclude_users)
|> Repo.all()
render(conn, "index.json", chats: chats)
user_id
|> Chat.for_user_query()
|> where([c], c.recipient not in ^exclude_users)
end
def create(%{assigns: %{user: user}} = conn, %{id: id}) do

View File

@ -12,7 +12,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileController do
plug(
Pleroma.Web.Plugs.OAuthScopesPlug,
%{scopes: ["write"], admin: true}
%{scopes: ["admin:write"]}
when action in [
:create,
:update,

View File

@ -11,7 +11,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackController do
plug(
Pleroma.Web.Plugs.OAuthScopesPlug,
%{scopes: ["write"], admin: true}
%{scopes: ["admin:write"]}
when action in [
:import_from_filesystem,
:remote,

View File

@ -0,0 +1,46 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ReportController do
use Pleroma.Web, :controller
alias Pleroma.Activity
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.AdminAPI.Report
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read:reports"]})
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaReportOperation
@doc "GET /api/v0/pleroma/reports"
def index(%{assigns: %{user: user}, body_params: params} = conn, _) do
params =
params
|> Map.put(:actor_id, user.ap_id)
reports = Utils.get_reports(params, Map.get(params, :page, 1), Map.get(params, :size, 20))
render(conn, "index.json", %{reports: reports, for: user})
end
@doc "GET /api/v0/pleroma/reports/:id"
def show(%{assigns: %{user: user}} = conn, %{id: id}) do
with %Activity{} = report <- Activity.get_report(id),
true <- report.actor == user.ap_id,
%{} = report_info <- Report.extract_report_info(report) do
render(conn, "show.json", Map.put(report_info, :for, user))
else
false ->
{:error, :not_found}
nil ->
{:error, :not_found}
e ->
{:error, inspect(e)}
end
end
end

View File

@ -0,0 +1,55 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ReportView do
use Pleroma.Web, :view
alias Pleroma.HTML
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.StatusView
def render("index.json", %{reports: reports, for: for_user}) do
%{
reports:
reports[:items]
|> Enum.map(&Report.extract_report_info/1)
|> Enum.map(&render(__MODULE__, "show.json", Map.put(&1, :for, for_user))),
total: reports[:total]
}
end
def render("show.json", %{
report: report,
user: actor,
account: account,
statuses: statuses,
for: for_user
}) do
created_at = Utils.to_masto_date(report.data["published"])
content =
unless is_nil(report.data["content"]) do
HTML.filter_tags(report.data["content"])
else
nil
end
%{
id: report.id,
account: AccountView.render("show.json", %{user: account, for: for_user}),
actor: AccountView.render("show.json", %{user: actor, for: for_user}),
content: content,
created_at: created_at,
statuses:
StatusView.render("index.json", %{
activities: statuses,
as: :activity,
for: for_user
}),
state: report.data["state"]
}
end
end

View File

@ -3,6 +3,10 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.EnsureAuthenticatedPlug do
@moduledoc """
Ensures _user_ authentication (app-bound user-unbound tokens are not accepted).
"""
import Plug.Conn
import Pleroma.Web.TranslationHelpers

View File

@ -3,6 +3,11 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug do
@moduledoc """
Ensures instance publicity or _user_ authentication
(app-bound user-unbound tokens are accepted only if the instance is public).
"""
import Pleroma.Web.TranslationHelpers
import Plug.Conn

View File

@ -28,6 +28,11 @@ defmodule Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug do
end
end
# App-bound token case (obtained with client_id and client_secret)
def call(%{assigns: %{token: %Token{user_id: nil}}} = conn, _) do
assign(conn, :user, nil)
end
def call(conn, _) do
conn
|> assign(:user, nil)

View File

@ -10,6 +10,8 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
"""
@behaviour Plug
@api_routes Pleroma.Web.get_api_routes()
def file_path(path, frontend_type \\ :primary) do
if configuration = Pleroma.Config.get([:frontends, frontend_type]) do
instance_static_path = Pleroma.Config.get([:instance, :static_dir], "instance/static")
@ -34,7 +36,8 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
end
def call(conn, opts) do
with false <- invalid_path?(conn.path_info),
with false <- api_route?(conn.path_info),
false <- invalid_path?(conn.path_info),
frontend_type <- Map.get(opts, :frontend_type, :primary),
path when not is_nil(path) <- file_path("", frontend_type) do
call_static(conn, opts, path)
@ -52,6 +55,10 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
defp invalid_path?([h | t], match), do: String.contains?(h, match) or invalid_path?(t)
defp invalid_path?([], _match), do: false
defp api_route?([h | _]) when h in @api_routes, do: true
defp api_route?([_ | t]), do: api_route?(t)
defp api_route?([]), do: false
defp call_static(conn, opts, from) do
opts = Map.put(opts, :from, from)
Plug.Static.call(conn, opts)

View File

@ -6,7 +6,6 @@ defmodule Pleroma.Web.Plugs.OAuthScopesPlug do
import Plug.Conn
import Pleroma.Web.Gettext
alias Pleroma.Config
alias Pleroma.Helpers.AuthHelper
use Pleroma.Web, :plug
@ -18,7 +17,6 @@ defmodule Pleroma.Web.Plugs.OAuthScopesPlug do
op = options[:op] || :|
token = assigns[:token]
scopes = transform_scopes(scopes, options)
matched_scopes = (token && filter_descendants(scopes, token.scopes)) || []
cond do
@ -57,13 +55,4 @@ defmodule Pleroma.Web.Plugs.OAuthScopesPlug do
end
)
end
@doc "Transforms scopes by applying supported options (e.g. :admin)"
def transform_scopes(scopes, options) do
if options[:admin] do
Config.oauth_admin_scopes(scopes)
else
scopes
end
end
end

View File

@ -37,11 +37,13 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug)
end
pipeline :expect_authentication do
# Note: expects _user_ authentication (user-unbound app-bound tokens don't qualify)
pipeline :expect_user_authentication do
plug(Pleroma.Web.Plugs.ExpectAuthenticatedCheckPlug)
end
pipeline :expect_public_instance_or_authentication do
# Note: expects public instance or _user_ authentication (user-unbound tokens don't qualify)
pipeline :expect_public_instance_or_user_authentication do
plug(Pleroma.Web.Plugs.ExpectPublicOrAuthenticatedCheckPlug)
end
@ -66,23 +68,30 @@ defmodule Pleroma.Web.Router do
plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
end
pipeline :api do
plug(:expect_public_instance_or_authentication)
pipeline :no_auth_or_privacy_expectations_api do
plug(:base_api)
plug(:after_auth)
plug(Pleroma.Web.Plugs.IdempotencyPlug)
end
# Pipeline for app-related endpoints (no user auth checks — app-bound tokens must be supported)
pipeline :app_api do
plug(:no_auth_or_privacy_expectations_api)
end
pipeline :api do
plug(:expect_public_instance_or_user_authentication)
plug(:no_auth_or_privacy_expectations_api)
end
pipeline :authenticated_api do
plug(:expect_authentication)
plug(:base_api)
plug(:after_auth)
plug(:expect_user_authentication)
plug(:no_auth_or_privacy_expectations_api)
plug(Pleroma.Web.Plugs.EnsureAuthenticatedPlug)
plug(Pleroma.Web.Plugs.IdempotencyPlug)
end
pipeline :admin_api do
plug(:expect_authentication)
plug(:expect_user_authentication)
plug(:base_api)
plug(Pleroma.Web.Plugs.AdminSecretAuthenticationPlug)
plug(:after_auth)
@ -131,7 +140,7 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
scope "/api/v1/pleroma", Pleroma.Web.TwitterAPI do
pipe_through(:pleroma_api)
get("/password_reset/:token", PasswordController, :reset, as: :reset_password)
@ -141,12 +150,12 @@ defmodule Pleroma.Web.Router do
get("/healthcheck", UtilController, :healthcheck)
end
scope "/api/pleroma", Pleroma.Web do
scope "/api/v1/pleroma", Pleroma.Web do
pipe_through(:pleroma_api)
post("/uploader_callback/:upload_path", UploaderController, :callback)
end
scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
scope "/api/v1/pleroma/admin", Pleroma.Web.AdminAPI do
pipe_through(:admin_api)
put("/users/disable_mfa", AdminAPIController, :disable_mfa)
@ -250,7 +259,7 @@ defmodule Pleroma.Web.Router do
post("/backups", AdminAPIController, :create_backup)
end
scope "/api/pleroma/emoji", Pleroma.Web.PleromaAPI do
scope "/api/v1/pleroma/emoji", Pleroma.Web.PleromaAPI do
scope "/pack" do
pipe_through(:admin_api)
@ -359,6 +368,12 @@ defmodule Pleroma.Web.Router do
get("/statuses/:id/reactions", EmojiReactionController, :index)
end
scope "/api/v0/pleroma", Pleroma.Web.PleromaAPI do
pipe_through(:authenticated_api)
get("/reports", ReportController, :index)
get("/reports/:id", ReportController, :show)
end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
scope [] do
pipe_through(:authenticated_api)
@ -411,6 +426,13 @@ defmodule Pleroma.Web.Router do
get("/federation_status", InstancesController, :show)
end
scope "/api/v2/pleroma", Pleroma.Web.PleromaAPI do
scope [] do
pipe_through(:authenticated_api)
get("/chats", ChatController, :index2)
end
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:authenticated_api)
@ -432,10 +454,9 @@ defmodule Pleroma.Web.Router do
post("/accounts/:id/mute", AccountController, :mute)
post("/accounts/:id/unmute", AccountController, :unmute)
get("/apps/verify_credentials", AppController, :verify_credentials)
get("/conversations", ConversationController, :index)
post("/conversations/:id/read", ConversationController, :mark_as_read)
delete("/conversations/:id", ConversationController, :delete)
get("/domain_blocks", DomainBlockController, :index)
post("/domain_blocks", DomainBlockController, :create)
@ -524,6 +545,13 @@ defmodule Pleroma.Web.Router do
put("/settings", MastoFEController, :put_settings)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:app_api)
post("/apps", AppController, :create)
get("/apps/verify_credentials", AppController, :verify_credentials)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:api)
@ -540,8 +568,6 @@ defmodule Pleroma.Web.Router do
get("/instance", InstanceController, :show)
get("/instance/peers", InstanceController, :peers)
post("/apps", AppController, :create)
get("/statuses", StatusController, :index)
get("/statuses/:id", StatusController, :show)
get("/statuses/:id/context", StatusController, :context)
@ -789,6 +815,7 @@ defmodule Pleroma.Web.Router do
scope "/", Pleroma.Web.Fallback do
get("/registration/:token", RedirectController, :registration_page)
get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
match(:*, "/api/pleroma*path", LegacyPleromaApiRerouterPlug, [])
get("/api*path", RedirectController, :api_not_implemented)
get("/*path", RedirectController, :redirector_with_preload)

View File

@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
def project do
[
app: :pleroma,
version: version("2.2.50"),
version: version("2.3.50"),
elixir: "~> 1.9",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
@ -159,7 +159,7 @@ defmodule Pleroma.Mixfile do
{:floki, "~> 0.27"},
{:timex, "~> 3.6"},
{:ueberauth, "~> 0.4"},
{:linkify, "~> 0.4.1"},
{:linkify, "~> 0.5.0"},
{:http_signatures, "~> 0.1.0"},
{:telemetry, "~> 0.3"},
{:poolboy, "~> 1.5"},

View File

@ -65,7 +65,7 @@
"jose": {:hex, :jose, "1.10.1", "16d8e460dae7203c6d1efa3f277e25b5af8b659febfc2f2eb4bacf87f128b80a", [:mix, :rebar3], [], "hexpm", "3c7ddc8a9394b92891db7c2771da94bf819834a1a4c92e30857b7d582e2f8257"},
"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"},
"linkify": {:hex, :linkify, "0.5.0", "e0ea8de73ff44742d6a889721221f4c4eccaad5284957ee9832ffeb347602d54", [:mix], [], "hexpm", "4ccd958350aee7c51c89e21f05b15d30596ebbba707e051d21766be1809df2d7"},
"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"},

View File

@ -4,7 +4,7 @@ defmodule Pleroma.Repo.Migrations.AddDefaultTextSearchConfig do
def change do
execute("DO $$
BEGIN
execute 'ALTER DATABASE '||current_database()||' SET default_text_search_config = ''english'' ';
execute 'ALTER DATABASE \"'||current_database()||'\" SET default_text_search_config = ''english'' ';
END
$$;")
end

View File

@ -0,0 +1,9 @@
defmodule Pleroma.Repo.Migrations.AddDiscloseClientToUsers do
use Ecto.Migration
def change do
alter table(:users) do
add(:disclose_client, :boolean, default: true)
end
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 726 B

After

Width:  |  Height:  |  Size: 1.0 KiB

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.3b02e2e5bd8cdca42216.js></script><script type=text/javascript src=/static/js/app.c6b8a1c86149ed63e6ff.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.102a26590d3ba87dd908.js></script><script type=text/javascript src=/static/js/app.2e518bb8cf82de7a72b0.js></script></body></html>

View File

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

View File

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

View File

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

View File

@ -1 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/11.a3e462fd9190986433f8.js","sourceRoot":""}
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/13.d02023d426b44a6886af.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/14.3546063198fc4cb3852c.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/14.8e7c0873d041b34efd84.js","sourceRoot":""}

View File

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

View File

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

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