From: FloatingGhost Date: Thu, 21 Jul 2022 10:29:28 +0000 (+0100) Subject: purge chat and shout endpoints X-Git-Url: https://git.squeep.com/?a=commitdiff_plain;h=0f132b802dde7f217ecb07767e0d34e3edb517b7;p=akkoma purge chat and shout endpoints --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 74b21f600..e3209cfcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `/api/v1/search` - `/api/v1/statuses/{id}/card` - LDAP authenticator +- Chats, they were half-baked. Just use PMs. ## 2022.07 diff --git a/config/config.exs b/config/config.exs index a7b38dbd0..21247bbe5 100644 --- a/config/config.exs +++ b/config/config.exs @@ -267,11 +267,6 @@ config :pleroma, :welcome, sender_nickname: nil, message: nil ], - chat_message: [ - enabled: false, - sender_nickname: nil, - message: nil - ], email: [ enabled: false, sender: nil, @@ -729,7 +724,8 @@ config :pleroma, :frontends, "mastodon-fe" => %{ "name" => "mastodon-fe", "git" => "https://akkoma.dev/AkkomaGang/masto-fe", - "build_url" => "https://akkoma-updates.s3-website.fr-par.scw.cloud/frontend/${ref}/masto-fe.zip", + "build_url" => + "https://akkoma-updates.s3-website.fr-par.scw.cloud/frontend/${ref}/masto-fe.zip", "build_dir" => "distribution", "ref" => "akkoma" }, diff --git a/config/description.exs b/config/description.exs index a4f115ce7..910953a91 100644 --- a/config/description.exs +++ b/config/description.exs @@ -946,7 +946,7 @@ config :pleroma, :config_description, [ key: :privileged_staff, type: :boolean, description: - "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" + "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses)" } ] }, @@ -984,35 +984,6 @@ config :pleroma, :config_description, [ } ] }, - %{ - key: :chat_message, - type: :keyword, - descpiption: "Chat message settings", - children: [ - %{ - key: :enabled, - type: :boolean, - description: "Enables sending a chat message to newly registered users" - }, - %{ - key: :message, - type: :string, - description: - "A message that will be sent to newly registered users as a chat message", - suggestions: [ - "Hello, welcome on board!" - ] - }, - %{ - key: :sender_nickname, - type: :string, - description: "The nickname of the local user that sends a welcome chat message", - suggestions: [ - "lain" - ] - } - ] - }, %{ key: :email, type: :keyword, @@ -2507,27 +2478,6 @@ config :pleroma, :config_description, [ } ] }, - %{ - group: :pleroma, - key: :shout, - type: :group, - description: "Pleroma shout settings", - children: [ - %{ - key: :enabled, - type: :boolean, - description: "Enables the backend Shoutbox chat feature." - }, - %{ - key: :limit, - type: :integer, - description: "Shout message character limit.", - suggestions: [ - 5_000 - ] - } - ] - }, %{ group: :pleroma, key: :http, diff --git a/docs/docs/configuration/cheatsheet.md b/docs/docs/configuration/cheatsheet.md index 85381d67c..fdbfb1a3e 100644 --- a/docs/docs/configuration/cheatsheet.md +++ b/docs/docs/configuration/cheatsheet.md @@ -8,11 +8,6 @@ For from source installations Akkoma configuration works by first importing the To add configuration to your config file, you can copy it from the base config. The latest version of it can be viewed [here](https://akkoma.dev/AkkomaGang/akkoma/src/branch/develop/config/config.exs). You can also use this file if you don't know how an option is supposed to be formatted. -## :shout - -* `enabled` - Enables the backend Shoutbox chat feature. Defaults to `true`. -* `limit` - Shout character limit. Defaults to `5_000` - ## :instance * `name`: The instance’s name. * `email`: Email used to reach an Administrator/Moderator of the instance. @@ -77,10 +72,6 @@ To add configuration to your config file, you can copy it from the base config. * `enabled`: Enables the send a direct message to a newly registered user. Defaults to `false`. * `sender_nickname`: The nickname of the local user that sends the welcome message. * `message`: A message that will be send to a newly registered users as a direct message. -* `chat_message`: - welcome message sent as a chat message. - * `enabled`: Enables the send a chat message to a newly registered user. Defaults to `false`. - * `sender_nickname`: The nickname of the local user that sends the welcome message. - * `message`: A message that will be send to a newly registered users as a chat message. * `email`: - welcome message sent as a email. * `enabled`: Enables the send a welcome email to a newly registered user. Defaults to `false`. * `sender`: The email address or tuple with `{nickname, email}` that will use as sender to the welcome email. diff --git a/docs/docs/development/API/admin_api.md b/docs/docs/development/API/admin_api.md index c46f83839..241e0b95c 100644 --- a/docs/docs/development/API/admin_api.md +++ b/docs/docs/development/API/admin_api.md @@ -1031,7 +1031,6 @@ Most of the settings will be applied in `runtime`, this means that you don't nee - `:hackney_pools` - `:connections_pool` - `:pools` - - `:chat` - partially settings inside these keys: - `:seconds_valid` in `Pleroma.Captcha` - `:proxy_remote` in `Pleroma.Upload` @@ -1411,127 +1410,6 @@ Loads json generated from `config/descriptions.exs`. ``` -## GET /api/v1/pleroma/admin/users/:nickname/chats - -### List a user's chats - -- Params: None - -- Response: - -```json -[ - { - "sender": { - "id": "someflakeid", - "username": "somenick", - ... - }, - "receiver": { - "id": "someflakeid", - "username": "somenick", - ... - }, - "id" : "1", - "unread" : 2, - "last_message" : {...}, // The last message in that chat - "updated_at": "2020-04-21T15:11:46.000Z" - } -] -``` - -## GET /api/v1/pleroma/admin/chats/:chat_id - -### View a single chat - -- Params: None - -- Response: - -```json -{ - "sender": { - "id": "someflakeid", - "username": "somenick", - ... - }, - "receiver": { - "id": "someflakeid", - "username": "somenick", - ... - }, - "id" : "1", - "unread" : 2, - "last_message" : {...}, // The last message in that chat - "updated_at": "2020-04-21T15:11:46.000Z" -} -``` - -## GET /api/v1/pleroma/admin/chats/:chat_id/messages - -### List the messages in a chat - -- Params: `max_id`, `min_id` - -- Response: - -```json -[ - { - "account_id": "someflakeid", - "chat_id": "1", - "content": "Check this out :firefox:", - "created_at": "2020-04-21T15:11:46.000Z", - "emojis": [ - { - "shortcode": "firefox", - "static_url": "https://dontbulling.me/emoji/Firefox.gif", - "url": "https://dontbulling.me/emoji/Firefox.gif", - "visible_in_picker": false - } - ], - "id": "13", - "unread": true - }, - { - "account_id": "someflakeid", - "chat_id": "1", - "content": "Whats' up?", - "created_at": "2020-04-21T15:06:45.000Z", - "emojis": [], - "id": "12", - "unread": false - } -] -``` - -## DELETE /api/v1/pleroma/admin/chats/:chat_id/messages/:message_id - -### Delete a single message - -- Params: None - -- Response: - -```json -{ - "account_id": "someflakeid", - "chat_id": "1", - "content": "Check this out :firefox:", - "created_at": "2020-04-21T15:11:46.000Z", - "emojis": [ - { - "shortcode": "firefox", - "static_url": "https://dontbulling.me/emoji/Firefox.gif", - "url": "https://dontbulling.me/emoji/Firefox.gif", - "visible_in_picker": false - } - ], - "id": "13", - "unread": false -} -``` - ## `GET /api/v1/pleroma/admin/instance_document/:document_name` ### Get an instance document diff --git a/docs/docs/development/API/chats.md b/docs/docs/development/API/chats.md deleted file mode 100644 index 69b214ab1..000000000 --- a/docs/docs/development/API/chats.md +++ /dev/null @@ -1,255 +0,0 @@ -# Chats - -Chats are a way to represent an IM-style conversation between two actors. They are not the same as direct messages and they are not `Status`es, even though they have a lot in common. - -## Why Chats? - -There are no 'visibility levels' in ActivityPub, their definition is purely a Mastodon convention. Direct Messaging between users on the fediverse has mostly been modeled by using ActivityPub addressing following Mastodon conventions on normal `Note` objects. In this case, a 'direct message' would be a message that has no followers addressed and also does not address the special public actor, but just the recipients in the `to` field. It would still be a `Note` and is presented with other `Note`s as a `Status` in the API. - -This is an awkward setup for a few reasons: - -- As DMs generally still follow the usual `Status` conventions, it is easy to accidentally pull somebody into a DM thread by mentioning them. (e.g. "I hate @badguy so much") -- It is possible to go from a publicly addressed `Status` to a DM reply, back to public, then to a 'followers only' reply, and so on. This can be become very confusing, as it is unclear which user can see which part of the conversation. -- The standard `Status` format of implicit addressing also leads to rather ugly results if you try to display the messages as a chat, because all the recipients are always mentioned by name in the message. -- As direct messages are posted with the same api call (and usually same frontend component) as public messages, accidentally making a public message private or vice versa can happen easily. Client bugs can also lead to this, accidentally making private messages public. - -As a measure to improve this situation, the `Conversation` concept and related Akkoma extensions were introduced. While it made it possible to work around a few of the issues, many of the problems remained and it didn't see much adoption because it was too complicated to use correctly. - -## Chats explained -For this reasons, Chats are a new and different entity, both in the API as well as in ActivityPub. A quick overview: - -- Chats are meant to represent an instant message conversation between two actors. For now these are only 1-on-1 conversations, but the other actor can be a group in the future. -- Chat messages have the ActivityPub type `ChatMessage`. They are not `Note`s. Servers that don't understand them will just drop them. -- The only addressing allowed in `ChatMessage`s is one single ActivityPub actor in the `to` field. -- There's always only one Chat between two actors. If you start chatting with someone and later start a 'new' Chat, the old Chat will be continued. -- `ChatMessage`s are posted with a different api, making it very hard to accidentally send a message to the wrong person. -- `ChatMessage`s don't show up in the existing timelines. -- Chats can never go from private to public. They are always private between the two actors. - -## Caveats - -- Chats are NOT E2E encrypted (yet). Security is still the same as email. - -## API - -In general, the way to send a `ChatMessage` is to first create a `Chat`, then post a message to that `Chat`. `Group`s will later be supported by making them a sub-type of `Account`. - -This is the overview of using the API. The API is also documented via OpenAPI, so you can view it and play with it by pointing SwaggerUI or a similar OpenAPI tool to `https://yourinstance.tld/api/openapi`. - -### Creating or getting a chat. - -To create or get an existing Chat for a certain recipient (identified by Account ID) -you can call: - -`POST /api/v1/pleroma/chats/by-account-id/:account_id` - -The account id is the normal FlakeId of the user -``` -POST /api/v1/pleroma/chats/by-account-id/someflakeid -``` - -If you already have the id of a chat, you can also use - -``` -GET /api/v1/pleroma/chats/:id -``` - -There will only ever be ONE Chat for you and a given recipient, so this call -will return the same Chat if you already have one with that user. - -Returned data: - -```json -{ - "account": { - "id": "someflakeid", - "username": "somenick", - ... - }, - "id" : "1", - "unread" : 2, - "last_message" : {...}, // The last message in that chat - "updated_at": "2020-04-21T15:11:46.000Z" -} -``` - -### Marking a chat as read - -To mark a number of messages in a chat up to a certain message as read, you can use - -`POST /api/v1/pleroma/chats/:id/read` - - -Parameters: -- last_read_id: Given this id, all chat messages until this one will be marked as read. Required. - - -Returned data: - -```json -{ - "account": { - "id": "someflakeid", - "username": "somenick", - ... - }, - "id" : "1", - "unread" : 0, - "updated_at": "2020-04-21T15:11:46.000Z" -} -``` - -### Marking a single chat message as read - -To set the `unread` property of a message to `false` - -`POST /api/v1/pleroma/chats/:id/messages/:message_id/read` - -Returned data: - -The modified chat message - -### Getting a list of Chats - -`GET /api/v1/pleroma/chats` - -This will return a list of chats that you have been involved in, sorted by their -last update (so new chats will be at the top). - -Parameters: - -- with_muted: Include chats from muted users (boolean). - -Returned data: - -```json -[ - { - "account": { - "id": "someflakeid", - "username": "somenick", - ... - }, - "id" : "1", - "unread" : 2, - "last_message" : {...}, // The last message in that chat - "updated_at": "2020-04-21T15:11:46.000Z" - } -] -``` - -The recipient of messages that are sent to this chat is given by their AP ID. -No pagination is implemented for now. - -### Getting the messages for a Chat - -For a given Chat id, you can get the associated messages with - -`GET /api/v1/pleroma/chats/:id/messages` - -This will return all messages, sorted by most recent to least recent. The usual -pagination options are implemented. - -Returned data: - -```json -[ - { - "account_id": "someflakeid", - "chat_id": "1", - "content": "Check this out :firefox:", - "created_at": "2020-04-21T15:11:46.000Z", - "emojis": [ - { - "shortcode": "firefox", - "static_url": "https://dontbulling.me/emoji/Firefox.gif", - "url": "https://dontbulling.me/emoji/Firefox.gif", - "visible_in_picker": false - } - ], - "id": "13", - "unread": true - }, - { - "account_id": "someflakeid", - "chat_id": "1", - "content": "Whats' up?", - "created_at": "2020-04-21T15:06:45.000Z", - "emojis": [], - "id": "12", - "unread": false, - "idempotency_key": "75442486-0874-440c-9db1-a7006c25a31f" - } -] -``` - -- idempotency_key: The copy of the `idempotency-key` HTTP request header that can be used for optimistic message sending. Included only during the first few minutes after the message creation. - -### Posting a chat message - -Posting a chat message for given Chat id works like this: - -`POST /api/v1/pleroma/chats/:id/messages` - -Parameters: -- content: The text content of the message. Optional if media is attached. -- media_id: The id of an upload that will be attached to the message. - -Currently, no formatting beyond basic escaping and emoji is implemented. - -Returned data: - -```json -{ - "account_id": "someflakeid", - "chat_id": "1", - "content": "Check this out :firefox:", - "created_at": "2020-04-21T15:11:46.000Z", - "emojis": [ - { - "shortcode": "firefox", - "static_url": "https://dontbulling.me/emoji/Firefox.gif", - "url": "https://dontbulling.me/emoji/Firefox.gif", - "visible_in_picker": false - } - ], - "id": "13", - "unread": false -} -``` - -### Deleting a chat message - -Deleting a chat message for given Chat id works like this: - -`DELETE /api/v1/pleroma/chats/:chat_id/messages/:message_id` - -Returned data is the deleted message. - -### Notifications - -There's a new `pleroma:chat_mention` notification, which has this form. It is not given out in the notifications endpoint by default, you need to explicitly request it with `include_types[]=pleroma:chat_mention`: - -```json -{ - "id": "someid", - "type": "pleroma:chat_mention", - "account": { ... } // User account of the sender, - "chat_message": { - "chat_id": "1", - "id": "10", - "content": "Hello", - "account_id": "someflakeid", - "unread": false - }, - "created_at": "somedate" -} -``` - -### Streaming - -There is an additional `user:pleroma_chat` stream. Incoming chat messages will make the current chat be sent to this `user` stream. The `event` of an incoming chat message is `pleroma:chat_update`. The payload is the updated chat with the incoming chat message in the `last_message` field. - -### Web Push - -If you want to receive push messages for this type, you'll need to add the `pleroma:chat_mention` type to your alerts in the push subscription. diff --git a/docs/docs/development/API/differences_in_mastoapi_responses.md b/docs/docs/development/API/differences_in_mastoapi_responses.md index 6130d716b..4465784bf 100644 --- a/docs/docs/development/API/differences_in_mastoapi_responses.md +++ b/docs/docs/development/API/differences_in_mastoapi_responses.md @@ -99,13 +99,11 @@ 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 Akkoma 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/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 ### Source @@ -159,15 +157,6 @@ The `type` value is `pleroma:emoji_reaction`. Has these fields: - `account`: The account of the user who reacted - `status`: The status that was reacted on -### ChatMention Notification (not default) - -This notification has to be requested explicitly. - -The `type` value is `pleroma:chat_mention` - -- `account`: The account who sent the message -- `chat_message`: The chat message - ### Report Notification (not default) This notification has to be requested explicitly. @@ -182,7 +171,7 @@ The `type` value is `pleroma:report` Accepts additional parameters: - `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`. -- `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`, `pleroma:chat_mention`, `pleroma:report`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`. +- `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`, `pleroma:report`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`. ## DELETE `/api/v1/notifications/destroy_multiple` @@ -240,7 +229,6 @@ Additional parameters can be added to the JSON body/Form data: - `pleroma_background_image` - sets the background image of the user. Can be set to "" (an empty string) to reset. - `discoverable` - if true, external services (search bots) etc. are allowed to index / list the account (regardless of this setting, user will still appear in regular search results). - `actor_type` - the type of this account. -- `accepts_chat_messages` - if false, this account will reject all chat messages. - `language` - user's preferred language for receiving emails (digest, confirmation, etc.) All images (avatar, banner and background) can be reset to the default by sending an empty string ("") instead of a file. @@ -300,7 +288,6 @@ Has these additional parameters (which are the same as in Akkoma-API): `GET /api/v1/instance` has additional fields - `max_toot_chars`: The maximum characters per post -- `chat_limit`: The maximum characters per chat message - `description_limit`: The maximum characters per image description - `poll_limits`: The limits of polls - `upload_limit`: The maximum upload file size @@ -321,7 +308,6 @@ Has these additional parameters (which are the same as in Akkoma-API): Permits these additional alert types: -- pleroma:chat_mention - pleroma:emoji_reaction ## Markers @@ -332,10 +318,6 @@ Has these additional fields under the `pleroma` object: ## Streaming -### Chats - -There is an additional `user:pleroma_chat` stream. Incoming chat messages will make the current chat be sent to this `user` stream. The `event` of an incoming chat message is `pleroma:chat_update`. The payload is the updated chat with the incoming chat message in the `last_message` field. - ### Remote timelines For viewing remote server timelines, there are `public:remote` and `public:remote:media` streams. Each of these accept a parameter like `?instance=lain.com`. diff --git a/docs/docs/development/API/nodeinfo.md b/docs/docs/development/API/nodeinfo.md index 30150ac47..08453cdc8 100644 --- a/docs/docs/development/API/nodeinfo.md +++ b/docs/docs/development/API/nodeinfo.md @@ -44,11 +44,8 @@ See also [the Nodeinfo standard](https://nodeinfo.diaspora.software/). "shareable_emoji_packs", "multifetch", "pleroma:api/v1/notifications:include_types_filter", - "chat", - "shout", "relay", - "pleroma_emoji_reactions", - "pleroma_chat_messages" + "pleroma_emoji_reactions" ], "federation":{ "enabled":true, @@ -204,11 +201,8 @@ See also [the Nodeinfo standard](https://nodeinfo.diaspora.software/). "shareable_emoji_packs", "multifetch", "pleroma:api/v1/notifications:include_types_filter", - "chat", - "shout", "relay", - "pleroma_emoji_reactions", - "pleroma_chat_messages" + "pleroma_emoji_reactions" ], "federation":{ "enabled":true, diff --git a/docs/docs/development/ap_extensions.md b/docs/docs/development/ap_extensions.md index 3d1caeb3e..bf9420272 100644 --- a/docs/docs/development/ap_extensions.md +++ b/docs/docs/development/ap_extensions.md @@ -26,40 +26,3 @@ Response: HTTP 201 Created with the object into the body, no `Location` header p The object given in the reponse should then be inserted into an Object's `attachment` field. -## ChatMessages - -`ChatMessage`s are the messages sent in 1-on-1 chats. They are similar to -`Note`s, but the addresing is done by having a single AP actor in the `to` -field. Addressing multiple actors is not allowed. These messages are always -private, there is no public version of them. They are created with a `Create` -activity. - -They are part of the `litepub` namespace as `http://litepub.social/ns#ChatMessage`. - -Example: - -```json -{ - "actor": "http://2hu.gensokyo/users/raymoo", - "id": "http://2hu.gensokyo/objects/1", - "object": { - "attributedTo": "http://2hu.gensokyo/users/raymoo", - "content": "You expected a cute girl? Too bad.", - "id": "http://2hu.gensokyo/objects/2", - "published": "2020-02-12T14:08:20Z", - "to": [ - "http://2hu.gensokyo/users/marisa" - ], - "type": "ChatMessage" - }, - "published": "2018-02-12T14:08:20Z", - "to": [ - "http://2hu.gensokyo/users/marisa" - ], - "type": "Create" -} -``` - -This setup does not prevent multi-user chats, but these will have to go through -a `Group`, which will be the recipient of the messages and then `Announce` them -to the users in the `Group`. diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 5801e930d..6bda2e1d9 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -77,8 +77,7 @@ defmodule Pleroma.Application do ] ++ elasticsearch_children() ++ task_children(@mix_env) ++ - dont_run_in_test(@mix_env) ++ - shout_child(shout_enabled?()) + dont_run_in_test(@mix_env) # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options @@ -93,11 +92,16 @@ defmodule Pleroma.Application do end opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts] - result = Supervisor.start_link(children, opts) - set_postgres_server_version() - - result + with {:ok, data} <- Supervisor.start_link(children, opts) do + set_postgres_server_version() + {:ok, data} + else + e -> + Logger.error("Failed to start!") + Logger.error("#{inspect(e)}") + e + end end defp set_postgres_server_version do @@ -173,11 +177,7 @@ defmodule Pleroma.Application do build_cachex("web_resp", limit: 2500), build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10), build_cachex("failed_proxy_url", limit: 2500), - build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000), - build_cachex("chat_message_id_idempotency_key", - expiration: chat_message_id_idempotency_key_expiration(), - limit: 500_000 - ) + build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000) ] end @@ -187,9 +187,6 @@ defmodule Pleroma.Application do defp idempotency_expiration, do: expiration(default: :timer.seconds(6 * 60 * 60), interval: :timer.seconds(60)) - defp chat_message_id_idempotency_key_expiration, - do: expiration(default: :timer.minutes(2), interval: :timer.seconds(60)) - defp seconds_valid_interval, do: :timer.seconds(Config.get!([Pleroma.Captcha, :seconds_valid])) @@ -201,8 +198,6 @@ defmodule Pleroma.Application do type: :worker } - defp shout_enabled?, do: Config.get([:shout, :enabled]) - defp dont_run_in_test(env) when env in [:test, :benchmark], do: [] defp dont_run_in_test(_) do @@ -222,15 +217,6 @@ defmodule Pleroma.Application do ] end - defp shout_child(true) do - [ - Pleroma.Web.ShoutChannel.ShoutChannelState, - {Phoenix.PubSub, [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2]} - ] - end - - defp shout_child(_), do: [] - defp task_children(:test) do [ %{ diff --git a/lib/pleroma/chat.ex b/lib/pleroma/chat.ex deleted file mode 100644 index bacff24b5..000000000 --- a/lib/pleroma/chat.ex +++ /dev/null @@ -1,97 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Chat do - use Ecto.Schema - - import Ecto.Changeset - import Ecto.Query - - alias Pleroma.Chat - alias Pleroma.Repo - alias Pleroma.User - - @moduledoc """ - Chat keeps a reference to ChatMessage conversations between a user and an recipient. The recipient can be a user (for now) or a group (not implemented yet). - - It is a helper only, to make it easy to display a list of chats with other people, ordered by last bump. The actual messages are retrieved by querying the recipients of the ChatMessages. - """ - - @type t :: %__MODULE__{} - @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true} - - schema "chats" do - belongs_to(:user, User, type: FlakeId.Ecto.CompatType) - field(:recipient, :string) - - timestamps() - end - - def changeset(struct, params) do - struct - |> cast(params, [:user_id, :recipient]) - |> validate_change(:recipient, fn - :recipient, recipient -> - case User.get_cached_by_ap_id(recipient) do - nil -> [recipient: "must be an existing user"] - _ -> [] - end - end) - |> validate_required([:user_id, :recipient]) - |> unique_constraint(:user_id, name: :chats_user_id_recipient_index) - end - - @spec get_by_user_and_id(User.t(), FlakeId.Ecto.CompatType.t()) :: - {:ok, t()} | {:error, :not_found} - def get_by_user_and_id(%User{id: user_id}, id) do - from(c in __MODULE__, - where: c.id == ^id, - where: c.user_id == ^user_id - ) - |> Repo.find_resource() - end - - @spec get_by_id(FlakeId.Ecto.CompatType.t()) :: t() | nil - def get_by_id(id) do - Repo.get(__MODULE__, id) - end - - @spec get(FlakeId.Ecto.CompatType.t(), String.t()) :: t() | nil - def get(user_id, recipient) do - Repo.get_by(__MODULE__, user_id: user_id, recipient: recipient) - end - - @spec get_or_create(FlakeId.Ecto.CompatType.t(), String.t()) :: - {:ok, t()} | {:error, Ecto.Changeset.t()} - def get_or_create(user_id, recipient) do - %__MODULE__{} - |> changeset(%{user_id: user_id, recipient: recipient}) - |> Repo.insert( - # Need to set something, otherwise we get nothing back at all - on_conflict: [set: [recipient: recipient]], - returning: true, - conflict_target: [:user_id, :recipient] - ) - end - - @spec bump_or_create(FlakeId.Ecto.CompatType.t(), String.t()) :: - {:ok, t()} | {:error, Ecto.Changeset.t()} - def bump_or_create(user_id, recipient) do - %__MODULE__{} - |> changeset(%{user_id: user_id, recipient: recipient}) - |> Repo.insert( - on_conflict: [set: [updated_at: NaiveDateTime.utc_now()]], - returning: true, - conflict_target: [:user_id, :recipient] - ) - end - - @spec for_user_query(FlakeId.Ecto.CompatType.t()) :: Ecto.Query.t() - def for_user_query(user_id) do - from(c in Chat, - where: c.user_id == ^user_id, - order_by: [desc: c.updated_at] - ) - end -end diff --git a/lib/pleroma/chat/message_reference.ex b/lib/pleroma/chat/message_reference.ex deleted file mode 100644 index 89537d155..000000000 --- a/lib/pleroma/chat/message_reference.ex +++ /dev/null @@ -1,117 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Chat.MessageReference do - @moduledoc """ - A reference that builds a relation between an AP chat message that a user can see and whether it has been seen - by them, or should be displayed to them. Used to build the chat view that is presented to the user. - """ - - use Ecto.Schema - - alias Pleroma.Chat - alias Pleroma.Object - alias Pleroma.Repo - - import Ecto.Changeset - import Ecto.Query - - @primary_key {:id, FlakeId.Ecto.Type, autogenerate: true} - - schema "chat_message_references" do - belongs_to(:object, Object) - belongs_to(:chat, Chat, type: FlakeId.Ecto.CompatType) - - field(:unread, :boolean, default: true) - - timestamps() - end - - def changeset(struct, params) do - struct - |> cast(params, [:object_id, :chat_id, :unread]) - |> validate_required([:object_id, :chat_id, :unread]) - end - - def get_by_id(id) do - __MODULE__ - |> Repo.get(id) - |> Repo.preload(:object) - end - - def delete(cm_ref) do - cm_ref - |> Repo.delete() - end - - def delete_for_object(%{id: object_id}) do - from(cr in __MODULE__, - where: cr.object_id == ^object_id - ) - |> Repo.delete_all() - end - - def for_chat_and_object(%{id: chat_id}, %{id: object_id}) do - __MODULE__ - |> Repo.get_by(chat_id: chat_id, object_id: object_id) - |> Repo.preload(:object) - end - - def for_chat_query(chat) do - from(cr in __MODULE__, - where: cr.chat_id == ^chat.id, - order_by: [desc: :id], - preload: [:object] - ) - end - - def last_message_for_chat(chat) do - chat - |> for_chat_query() - |> limit(1) - |> Repo.one() - end - - def create(chat, object, unread) do - params = %{ - chat_id: chat.id, - object_id: object.id, - unread: unread - } - - %__MODULE__{} - |> changeset(params) - |> Repo.insert() - end - - def unread_count_for_chat(chat) do - chat - |> for_chat_query() - |> where([cmr], cmr.unread == true) - |> Repo.aggregate(:count) - end - - def mark_as_read(cm_ref) do - cm_ref - |> changeset(%{unread: false}) - |> Repo.update() - end - - def set_all_seen_for_chat(chat, last_read_id \\ nil) do - query = - chat - |> for_chat_query() - |> exclude(:order_by) - |> exclude(:preload) - |> where([cmr], cmr.unread == true) - - if last_read_id do - query - |> where([cmr], cmr.id <= ^last_read_id) - else - query - end - |> Repo.update_all(set: [unread: false]) - end -end diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index 911357841..3675c5e4a 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -176,7 +176,6 @@ defmodule Pleroma.Config.DeprecationWarnings do check_activity_expiration_config(), check_remote_ip_plug_name(), check_uploders_s3_public_endpoint(), - check_old_chat_shoutbox(), check_quarantined_instances_tuples(), check_transparency_exclusions_tuples(), check_simple_policy_tuples() @@ -308,27 +307,4 @@ defmodule Pleroma.Config.DeprecationWarnings do :ok end end - - @spec check_old_chat_shoutbox() :: :ok | nil - def check_old_chat_shoutbox do - instance_config = Pleroma.Config.get([:instance]) - chat_config = Pleroma.Config.get([:chat]) || [] - - use_old_config = - Keyword.has_key?(instance_config, :chat_limit) or - Keyword.has_key?(chat_config, :enabled) - - if use_old_config do - Logger.error(""" - !!!DEPRECATION WARNING!!! - Your config is using the old namespace for the Shoutbox configuration. You need to convert to the new namespace. e.g., - \n* `config :pleroma, :chat, enabled` and `config :pleroma, :instance, chat_limit` are now equal to: - \n* `config :pleroma, :shout, enabled` and `config :pleroma, :shout, limit` - """) - - :error - else - :ok - end - end end diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex index 4676429ae..a4dc92ee0 100644 --- a/lib/pleroma/config/transfer_task.ex +++ b/lib/pleroma/config/transfer_task.ex @@ -15,7 +15,6 @@ defmodule Pleroma.Config.TransferTask do defp reboot_time_keys, do: [ - {:pleroma, :shout}, {:pleroma, Oban}, {:pleroma, :rate_limit}, {:pleroma, :markup}, diff --git a/lib/pleroma/migration_helper/notification_backfill.ex b/lib/pleroma/migration_helper/notification_backfill.ex index 62b710f82..75d20a402 100644 --- a/lib/pleroma/migration_helper/notification_backfill.ex +++ b/lib/pleroma/migration_helper/notification_backfill.ex @@ -3,7 +3,6 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.MigrationHelper.NotificationBackfill do - alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User @@ -79,14 +78,5 @@ defmodule Pleroma.MigrationHelper.NotificationBackfill do end end - defp type_from_activity_object(%{data: %{"type" => "Create", "object" => %{}}}), do: "mention" - - defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do - object = Object.get_by_ap_id(activity.data["object"]) - - case object && object.data["type"] do - "ChatMessage" -> "pleroma:chat_mention" - _ -> "mention" - end - end + defp type_from_activity_object(%{data: %{"type" => "Create"}}), do: "mention" end diff --git a/lib/pleroma/moderation_log.ex b/lib/pleroma/moderation_log.ex index adb51d33a..7da8d0c63 100644 --- a/lib/pleroma/moderation_log.ex +++ b/lib/pleroma/moderation_log.ex @@ -237,17 +237,6 @@ defmodule Pleroma.ModerationLog do insert_log_entry_with_message(%ModerationLog{data: data}) end - def insert_log(%{actor: %User{} = actor, action: "chat_message_delete", subject_id: subject_id}) do - %ModerationLog{ - data: %{ - "actor" => %{"nickname" => actor.nickname}, - "action" => "chat_message_delete", - "subject_id" => subject_id - } - } - |> insert_log_entry_with_message() - end - @spec insert_log_entry_with_message(ModerationLog) :: {:ok, ModerationLog} | {:error, any} defp insert_log_entry_with_message(entry) do entry.data["message"] @@ -554,16 +543,6 @@ defmodule Pleroma.ModerationLog do "@#{actor_nickname} updated users: #{users_to_nicknames_string(subjects)}" end - def get_log_entry_message(%ModerationLog{ - data: %{ - "actor" => %{"nickname" => actor_nickname}, - "action" => "chat_message_delete", - "subject_id" => subject_id - } - }) do - "@#{actor_nickname} deleted chat message ##{subject_id}" - end - def get_log_entry_message(%ModerationLog{ data: %{ "actor" => %{"nickname" => actor_nickname}, diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 2ab09495d..d8878338e 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -68,7 +68,6 @@ defmodule Pleroma.Notification do follow_request mention move - pleroma:chat_mention pleroma:emoji_reaction pleroma:report reblog @@ -444,16 +443,7 @@ defmodule Pleroma.Notification do end end - defp type_from_activity_object(%{data: %{"type" => "Create", "object" => %{}}}), do: "mention" - - defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do - object = Object.get_by_ap_id(activity.data["object"]) - - case object && object.data["type"] do - "ChatMessage" -> "pleroma:chat_mention" - _ -> "mention" - end - end + defp type_from_activity_object(%{data: %{"type" => "Create"}}), do: "mention" # TODO move to sql, too. def create_notification(%Activity{} = activity, %User{} = user, opts \\ []) do diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 9ff52c94f..d66283632 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -145,7 +145,6 @@ defmodule Pleroma.User do field(:also_known_as, {:array, ObjectValidators.ObjectID}, default: []) field(:inbox, :string) field(:shared_inbox, :string) - field(:accepts_chat_messages, :boolean, default: nil) field(:last_active_at, :naive_datetime) field(:disclose_client, :boolean, default: true) field(:pinned_objects, :map, default: %{}) @@ -455,7 +454,6 @@ defmodule Pleroma.User do :invisible, :actor_type, :also_known_as, - :accepts_chat_messages, :pinned_objects ] ) @@ -516,7 +514,6 @@ defmodule Pleroma.User do :pleroma_settings_store, :is_discoverable, :actor_type, - :accepts_chat_messages, :disclose_client ] ) @@ -667,7 +664,6 @@ defmodule Pleroma.User do bio_limit = Config.get([:instance, :user_bio_length], 5000) name_limit = Config.get([:instance, :user_name_length], 100) reason_limit = Config.get([:instance, :registration_reason_length], 500) - params = Map.put_new(params, :accepts_chat_messages, true) confirmed? = if is_nil(opts[:confirmed]) do @@ -695,7 +691,6 @@ defmodule Pleroma.User do :password, :password_confirmation, :emoji, - :accepts_chat_messages, :registration_reason, :language ]) @@ -798,8 +793,7 @@ defmodule Pleroma.User do {:ok, user} <- set_cache(user), {:ok, _} <- maybe_send_registration_email(user), {:ok, _} <- maybe_send_welcome_email(user), - {:ok, _} <- maybe_send_welcome_message(user), - {:ok, _} <- maybe_send_welcome_chat_message(user) do + {:ok, _} <- maybe_send_welcome_message(user) do {:ok, user} end end @@ -833,15 +827,6 @@ defmodule Pleroma.User do end end - defp maybe_send_welcome_chat_message(user) do - if User.WelcomeChatMessage.enabled?() do - User.WelcomeChatMessage.post_message(user) - {:ok, :enqueued} - else - {:ok, :noop} - end - end - defp maybe_send_welcome_email(%User{email: email} = user) when is_binary(email) do if User.WelcomeEmail.enabled?() do User.WelcomeEmail.send_email(user) diff --git a/lib/pleroma/user/welcome_chat_message.ex b/lib/pleroma/user/welcome_chat_message.ex deleted file mode 100644 index 0d6690e34..000000000 --- a/lib/pleroma/user/welcome_chat_message.ex +++ /dev/null @@ -1,45 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.User.WelcomeChatMessage do - alias Pleroma.Config - alias Pleroma.User - alias Pleroma.Web.CommonAPI - - @spec enabled?() :: boolean() - def enabled?, do: Config.get([:welcome, :chat_message, :enabled], false) - - @spec post_message(User.t()) :: {:ok, Pleroma.Activity.t() | nil} - def post_message(user) do - [:welcome, :chat_message, :sender_nickname] - |> Config.get(nil) - |> fetch_sender() - |> do_post(user, welcome_message()) - end - - defp do_post(%User{} = sender, recipient, message) - when is_binary(message) do - CommonAPI.post_chat_message( - sender, - recipient, - message - ) - end - - defp do_post(_sender, _recipient, _message), do: {:ok, nil} - - defp fetch_sender(nickname) when is_binary(nickname) do - with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do - user - else - _ -> nil - end - end - - defp fetch_sender(_), do: nil - - defp welcome_message do - Config.get([:welcome, :chat_message, :message], nil) - end -end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 3583f1626..29055668b 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -97,7 +97,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp increase_replies_count_if_reply(_create_data), do: :noop - @object_types ~w[ChatMessage Question Answer Audio Video Event Article Note Page] + @object_types ~w[Question Answer Audio Video Event Article Note Page] @impl true def persist(%{"type" => type} = object, meta) when type in @object_types do with {:ok, object} <- Object.create(object) do @@ -1188,18 +1188,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - defp exclude_chat_messages(query, %{include_chat_messages: true}), do: query - - defp exclude_chat_messages(query, _) do - if has_named_binding?(query, :object) do - from([activity, object: o] in query, - where: fragment("not(?->>'type' = ?)", o.data, "ChatMessage") - ) - else - query - end - end - defp exclude_invisible_actors(query, %{invisible_actors: true}), do: query defp exclude_invisible_actors(query, _opts) do @@ -1340,7 +1328,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_filtered(opts) |> Activity.restrict_deactivated_users() |> exclude_poll_votes(opts) - |> exclude_chat_messages(opts) |> exclude_invisible_actors(opts) |> exclude_visibility(opts) @@ -1462,8 +1449,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end) is_locked = data["manuallyApprovesFollowers"] || false - capabilities = data["capabilities"] || %{} - accepts_chat_messages = capabilities["acceptsChatMessages"] data = Transmogrifier.maybe_fix_user_object(data) is_discoverable = data["discoverable"] || false invisible = data["invisible"] || false @@ -1507,7 +1492,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do public_key: public_key, inbox: data["inbox"], shared_inbox: shared_inbox, - accepts_chat_messages: accepts_chat_messages, pinned_objects: pinned_objects } diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex index 006e92bf4..8c51b8d63 100644 --- a/lib/pleroma/web/activity_pub/builder.ex +++ b/lib/pleroma/web/activity_pub/builder.ex @@ -183,30 +183,6 @@ defmodule Pleroma.Web.ActivityPub.Builder do end end - def chat_message(actor, recipient, content, opts \\ []) do - basic = %{ - "id" => Utils.generate_object_id(), - "actor" => actor.ap_id, - "type" => "ChatMessage", - "to" => [recipient], - "content" => content, - "published" => DateTime.utc_now() |> DateTime.to_iso8601(), - "emoji" => Emoji.Formatter.get_emoji_map(content) - } - - case opts[:attachment] do - %Object{data: attachment_data} -> - { - :ok, - Map.put(basic, "attachment", attachment_data), - [] - } - - _ -> - {:ok, basic, []} - end - end - def answer(user, object, name) do {:ok, %{ diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index 187cd0cfd..283cd884c 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -23,8 +23,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator alias Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator - alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator - alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator alias Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator alias Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator @@ -83,21 +81,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do end end - def validate( - %{"type" => "Create", "object" => %{"type" => "ChatMessage"} = object} = create_activity, - meta - ) do - with {:ok, object_data} <- cast_and_apply(object), - meta = Keyword.put(meta, :object_data, object_data |> stringify_keys), - {:ok, create_activity} <- - create_activity - |> CreateChatMessageValidator.cast_and_validate(meta) - |> Ecto.Changeset.apply_action(:insert) do - create_activity = stringify_keys(create_activity) - {:ok, create_activity, meta} - end - end - def validate( %{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity, meta @@ -143,7 +126,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do def validate(%{"type" => type} = object, meta) when type in ~w[Accept Reject Follow Update Like EmojiReact Announce - ChatMessage Answer] do + Answer] do validator = case type do "Accept" -> AcceptRejectValidator @@ -153,7 +136,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do "Like" -> LikeValidator "EmojiReact" -> EmojiReactValidator "Announce" -> AnnounceValidator - "ChatMessage" -> ChatMessageValidator "Answer" -> AnswerValidator end @@ -178,10 +160,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do def validate(o, m), do: {:error, {:validator_not_set, {o, m}}} - def cast_and_apply(%{"type" => "ChatMessage"} = object) do - ChatMessageValidator.cast_and_apply(object) - end - def cast_and_apply(%{"type" => "Question"} = object) do QuestionValidator.cast_and_apply(object) end diff --git a/lib/pleroma/web/activity_pub/object_validators/chat_message_validator.ex b/lib/pleroma/web/activity_pub/object_validators/chat_message_validator.ex deleted file mode 100644 index b153156b0..000000000 --- a/lib/pleroma/web/activity_pub/object_validators/chat_message_validator.ex +++ /dev/null @@ -1,129 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator do - use Ecto.Schema - - alias Pleroma.EctoType.ActivityPub.ObjectValidators - alias Pleroma.User - alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator - - import Ecto.Changeset - import Pleroma.Web.ActivityPub.Transmogrifier, only: [fix_emoji: 1] - - @primary_key false - @derive Jason.Encoder - - embedded_schema do - field(:id, ObjectValidators.ObjectID, primary_key: true) - field(:to, ObjectValidators.Recipients, default: []) - field(:type, :string) - field(:content, ObjectValidators.SafeText) - field(:actor, ObjectValidators.ObjectID) - field(:published, ObjectValidators.DateTime) - field(:emoji, ObjectValidators.Emoji, default: %{}) - - embeds_one(:attachment, AttachmentValidator) - end - - def cast_and_apply(data) do - data - |> cast_data - |> apply_action(:insert) - end - - def cast_and_validate(data) do - data - |> cast_data() - |> validate_data() - end - - def cast_data(data) do - %__MODULE__{} - |> changeset(data) - end - - def fix(data) do - data - |> fix_emoji() - |> fix_attachment() - |> Map.put_new("actor", data["attributedTo"]) - end - - # Throws everything but the first one away - def fix_attachment(%{"attachment" => [attachment | _]} = data) do - data - |> Map.put("attachment", attachment) - end - - def fix_attachment(data), do: data - - def changeset(struct, data) do - data = fix(data) - - struct - |> cast(data, List.delete(__schema__(:fields), :attachment)) - |> cast_embed(:attachment) - end - - defp validate_data(data_cng) do - data_cng - |> validate_inclusion(:type, ["ChatMessage"]) - |> validate_required([:id, :actor, :to, :type, :published]) - |> validate_content_or_attachment() - |> validate_length(:to, is: 1) - |> validate_length(:content, max: Pleroma.Config.get([:instance, :remote_limit])) - |> validate_local_concern() - end - - def validate_content_or_attachment(cng) do - attachment = get_field(cng, :attachment) - - if attachment do - cng - else - cng - |> validate_required([:content]) - end - end - - @doc """ - Validates the following - - If both users are in our system - - If at least one of the users in this ChatMessage is a local user - - If the recipient is not blocking the actor - - If the recipient is explicitly not accepting chat messages - """ - def validate_local_concern(cng) do - with actor_ap <- get_field(cng, :actor), - {_, %User{} = actor} <- {:find_actor, User.get_cached_by_ap_id(actor_ap)}, - {_, %User{} = recipient} <- - {:find_recipient, User.get_cached_by_ap_id(get_field(cng, :to) |> hd())}, - {_, false} <- {:not_accepting_chats?, recipient.accepts_chat_messages == false}, - {_, false} <- {:blocking_actor?, User.blocks?(recipient, actor)}, - {_, true} <- {:local?, Enum.any?([actor, recipient], & &1.local)} do - cng - else - {:blocking_actor?, true} -> - cng - |> add_error(:actor, "actor is blocked by recipient") - - {:not_accepting_chats?, true} -> - cng - |> add_error(:to, "recipient does not accept chat messages") - - {:local?, false} -> - cng - |> add_error(:actor, "actor and recipient are both remote") - - {:find_actor, _} -> - cng - |> add_error(:actor, "can't find user") - - {:find_recipient, _} -> - cng - |> add_error(:to, "can't find user") - end - end -end diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex index 011cf66ca..37ec860dc 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex @@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFields do alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator - # Activities and Objects, except (Create)ChatMessage + # Activities and Objects defmacro message_fields do quote bind_quoted: binding() do field(:type, :string) @@ -38,7 +38,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFields do end end - # Basically objects that aren't ChatMessage and Answer + # Basically objects that aren't Answer defmacro status_object_fields do quote bind_quoted: binding() do # TODO: Remove actor on objects diff --git a/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex deleted file mode 100644 index 6551f64ca..000000000 --- a/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex +++ /dev/null @@ -1,96 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -# NOTES -# - Can probably be a generic create validator -# - doesn't embed, will only get the object id -defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator do - use Ecto.Schema - alias Pleroma.EctoType.ActivityPub.ObjectValidators - - alias Pleroma.Object - - import Ecto.Changeset - import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations - - @primary_key false - - embedded_schema do - quote do - unquote do - import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields - activity_fields() - end - end - - field(:id, ObjectValidators.ObjectID, primary_key: true) - field(:type, :string) - field(:to, ObjectValidators.Recipients, default: []) - end - - def cast_and_apply(data) do - data - |> cast_data - |> apply_action(:insert) - end - - def cast_data(data) do - cast(%__MODULE__{}, data, __schema__(:fields)) - end - - def cast_and_validate(data, meta \\ []) do - cast_data(data) - |> validate_data(meta) - end - - defp validate_data(cng, meta) do - cng - |> validate_required([:id, :actor, :to, :type, :object]) - |> validate_inclusion(:type, ["Create"]) - |> validate_actor_presence() - |> validate_recipients_match(meta) - |> validate_actors_match(meta) - |> validate_object_nonexistence() - end - - def validate_object_nonexistence(cng) do - cng - |> validate_change(:object, fn :object, object_id -> - if Object.get_cached_by_ap_id(object_id) do - [{:object, "The object to create already exists"}] - else - [] - end - end) - end - - def validate_actors_match(cng, meta) do - object_actor = meta[:object_data]["actor"] - - cng - |> validate_change(:actor, fn :actor, actor -> - if actor == object_actor do - [] - else - [{:actor, "Actor doesn't match with object actor"}] - end - end) - end - - def validate_recipients_match(cng, meta) do - object_recipients = meta[:object_data]["to"] || [] - - cng - |> validate_change(:to, fn :to, recipients -> - activity_set = MapSet.new(recipients) - object_set = MapSet.new(object_recipients) - - if MapSet.equal?(activity_set, object_set) do - [] - else - [{:to, "Recipients don't match with object recipients"}] - end - end) - end -end diff --git a/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex b/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex index f0c99356e..a08e8ebe0 100644 --- a/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex @@ -48,7 +48,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator do Answer Article Audio - ChatMessage Event Note Page diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index e2371b693..439268470 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -10,8 +10,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do collection, and so on. """ alias Pleroma.Activity - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference alias Pleroma.FollowingRelationship alias Pleroma.Notification alias Pleroma.Object @@ -27,7 +25,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do require Logger - @cachex Pleroma.Config.get([:cachex, :provider], Cachex) @logger Pleroma.Config.get([:side_effects, :logger], Logger) @behaviour Pleroma.Web.ActivityPub.SideEffects.Handling @@ -306,8 +303,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do Object.decrease_replies_count(in_reply_to) end - MessageReference.delete_for_object(deleted_object) - ap_streamer().stream_out(object) ap_streamer().stream_out_participations(deleted_object, user) :ok @@ -400,41 +395,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do {:ok, object, meta} end - def handle_object_creation(%{"type" => "ChatMessage"} = object, _activity, meta) do - with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do - actor = User.get_cached_by_ap_id(object.data["actor"]) - recipient = User.get_cached_by_ap_id(hd(object.data["to"])) - - streamables = - [[actor, recipient], [recipient, actor]] - |> Enum.uniq() - |> Enum.map(fn [user, other_user] -> - if user.local do - {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id) - {:ok, cm_ref} = MessageReference.create(chat, object, user.ap_id != actor.ap_id) - - @cachex.put( - :chat_message_id_idempotency_key_cache, - cm_ref.id, - meta[:idempotency_key] - ) - - { - ["user", "user:pleroma_chat"], - {user, %{cm_ref | chat: chat, object: object}} - } - end - end) - |> Enum.filter(& &1) - - meta = - meta - |> add_streamables(streamables) - - {:ok, object, meta} - end - end - def handle_object_creation(%{"type" => "Question"} = object, activity, meta) do with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do PollWorker.schedule_poll_end(activity) @@ -533,13 +493,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do meta end - defp add_streamables(meta, streamables) do - existing = Keyword.get(meta, :streamables, []) - - meta - |> Keyword.put(:streamables, streamables ++ existing) - end - defp add_notifications(meta, notifications) do existing = Keyword.get(meta, :notifications, []) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index cf072f7ac..115dfc470 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -416,7 +416,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do %{"type" => "Create", "object" => %{"type" => objtype, "id" => obj_id}} = data, options ) - when objtype in ~w{Question Answer ChatMessage Audio Video Event Article Note Page} do + when objtype in ~w{Question Answer Audio Video Event Article Note Page} do fetch_options = Keyword.put(options, :depth, (options[:depth] || 0) + 1) object = @@ -846,9 +846,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do Map.put(object, "attributedTo", attributed_to) end - # TODO: Revisit this - def prepare_attachments(%{"type" => "ChatMessage"} = object), do: object - def prepare_attachments(object) do attachments = object diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 344da19d3..760515f34 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -83,14 +83,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do fields = Enum.map(user.fields, &Map.put(&1, "type", "PropertyValue")) - capabilities = - if is_boolean(user.accepts_chat_messages) do - %{ - "acceptsChatMessages" => user.accepts_chat_messages - } - else - %{} - end + capabilities = %{} %{ "id" => user.ap_id, diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex index 50aa294f0..1d7ac78a0 100644 --- a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex @@ -52,12 +52,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do when action in [:list_user_statuses] ) - plug( - OAuthScopesPlug, - %{scopes: ["admin:read:chats"]} - when action in [:list_user_chats] - ) - plug( OAuthScopesPlug, %{scopes: ["admin:read"]} @@ -106,20 +100,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do end end - def list_user_chats(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname} = _params) do - with %User{id: user_id} <- User.get_cached_by_nickname_or_id(nickname, for: admin) do - chats = - Pleroma.Chat.for_user_query(user_id) - |> Pleroma.Repo.all() - - conn - |> put_view(AdminAPI.ChatView) - |> render("index.json", chats: chats) - else - _ -> {:error, :not_found} - end - end - def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do with {:ok, _} <- User.tag(nicknames, tags) do ModerationLog.insert_log(%{ diff --git a/lib/pleroma/web/admin_api/controllers/chat_controller.ex b/lib/pleroma/web/admin_api/controllers/chat_controller.ex deleted file mode 100644 index ff20c8604..000000000 --- a/lib/pleroma/web/admin_api/controllers/chat_controller.ex +++ /dev/null @@ -1,85 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.AdminAPI.ChatController do - use Pleroma.Web, :controller - - alias Pleroma.Activity - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.ModerationLog - alias Pleroma.Pagination - alias Pleroma.Web.AdminAPI - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView - alias Pleroma.Web.Plugs.OAuthScopesPlug - - require Logger - - plug(Pleroma.Web.ApiSpec.CastAndValidate) - - plug( - OAuthScopesPlug, - %{scopes: ["admin:read:chats"]} when action in [:show, :messages] - ) - - plug( - OAuthScopesPlug, - %{scopes: ["admin:write:chats"]} when action in [:delete_message] - ) - - action_fallback(Pleroma.Web.AdminAPI.FallbackController) - - defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.ChatOperation - - def delete_message(%{assigns: %{user: user}} = conn, %{ - message_id: message_id, - id: chat_id - }) do - with %MessageReference{object: %{data: %{"id" => object_ap_id}}} = cm_ref <- - MessageReference.get_by_id(message_id), - ^chat_id <- to_string(cm_ref.chat_id), - %Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(object_ap_id), - {:ok, _} <- CommonAPI.delete(activity_id, user) do - ModerationLog.insert_log(%{ - action: "chat_message_delete", - actor: user, - subject_id: message_id - }) - - conn - |> put_view(MessageReferenceView) - |> render("show.json", chat_message_reference: cm_ref) - else - _e -> - {:error, :could_not_delete} - end - end - - def messages(conn, %{id: id} = params) do - with %Chat{} = chat <- Chat.get_by_id(id) do - cm_refs = - chat - |> MessageReference.for_chat_query() - |> Pagination.fetch_paginated(params) - - conn - |> put_view(MessageReferenceView) - |> render("index.json", chat_message_references: cm_refs) - else - _ -> - conn - |> put_status(:not_found) - |> json(%{error: "not found"}) - end - end - - def show(conn, %{id: id}) do - with %Chat{} = chat <- Chat.get_by_id(id) do - conn - |> put_view(AdminAPI.ChatView) - |> render("show.json", chat: chat) - end - end -end diff --git a/lib/pleroma/web/admin_api/views/chat_view.ex b/lib/pleroma/web/admin_api/views/chat_view.ex deleted file mode 100644 index 2a2015ad1..000000000 --- a/lib/pleroma/web/admin_api/views/chat_view.ex +++ /dev/null @@ -1,30 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.AdminAPI.ChatView do - use Pleroma.Web, :view - - alias Pleroma.Chat - alias Pleroma.User - alias Pleroma.Web.MastodonAPI - alias Pleroma.Web.PleromaAPI - - def render("index.json", %{chats: chats} = opts) do - render_many(chats, __MODULE__, "show.json", Map.delete(opts, :chats)) - end - - def render("show.json", %{chat: %Chat{user_id: user_id}} = opts) do - user = User.get_by_id(user_id) - sender = MastodonAPI.AccountView.render("show.json", user: user, skip_visibility_check: true) - - serialized_chat = PleromaAPI.ChatView.render("show.json", opts) - - serialized_chat - |> Map.put(:sender, sender) - |> Map.put(:receiver, serialized_chat[:account]) - |> Map.delete(:account) - end - - def render(view, opts), do: PleromaAPI.ChatView.render(view, opts) -end diff --git a/lib/pleroma/web/api_spec.ex b/lib/pleroma/web/api_spec.ex index 66ae7dcf8..8ac5c8b94 100644 --- a/lib/pleroma/web/api_spec.ex +++ b/lib/pleroma/web/api_spec.ex @@ -84,7 +84,6 @@ defmodule Pleroma.Web.ApiSpec do %{ "name" => "Administration", "tags" => [ - "Chat administration", "Emoji pack administration", "Frontend managment", "Instance configuration", @@ -114,7 +113,6 @@ defmodule Pleroma.Web.ApiSpec do ] }, %{"name" => "Instance", "tags" => ["Custom emojis"]}, - %{"name" => "Messaging", "tags" => ["Chats", "Conversations"]}, %{ "name" => "Statuses", "tags" => [ diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index bdbae9b74..b1f4932ee 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -595,11 +595,6 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do nullable: true, description: "Whether manual approval of follow requests is required." }, - accepts_chat_messages: %Schema{ - allOf: [BooleanLike], - nullable: true, - description: "Whether the user accepts receiving chat messages." - }, fields_attributes: %Schema{ nullable: true, oneOf: [ diff --git a/lib/pleroma/web/api_spec/operations/admin/chat_operation.ex b/lib/pleroma/web/api_spec/operations/admin/chat_operation.ex deleted file mode 100644 index 57906445e..000000000 --- a/lib/pleroma/web/api_spec/operations/admin/chat_operation.ex +++ /dev/null @@ -1,96 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do - alias OpenApiSpex.Operation - alias Pleroma.Web.ApiSpec.Schemas.Chat - alias Pleroma.Web.ApiSpec.Schemas.ChatMessage - - import Pleroma.Web.ApiSpec.Helpers - - def open_api_operation(action) do - operation = String.to_existing_atom("#{action}_operation") - apply(__MODULE__, operation, []) - end - - def delete_message_operation do - %Operation{ - tags: ["Chat administration"], - summary: "Delete an individual chat message", - operationId: "AdminAPI.ChatController.delete_message", - parameters: [ - Operation.parameter(:id, :path, :string, "The ID of the Chat"), - Operation.parameter(:message_id, :path, :string, "The ID of the message") - ], - responses: %{ - 200 => - Operation.response( - "The deleted ChatMessage", - "application/json", - ChatMessage - ) - }, - security: [ - %{ - "oAuth" => ["admin:write:chats"] - } - ] - } - end - - def messages_operation do - %Operation{ - tags: ["Chat administration"], - summary: "Get chat's messages", - operationId: "AdminAPI.ChatController.messages", - parameters: - [Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++ - pagination_params(), - responses: %{ - 200 => - Operation.response( - "The messages in the chat", - "application/json", - Pleroma.Web.ApiSpec.ChatOperation.chat_messages_response() - ) - }, - security: [ - %{ - "oAuth" => ["admin:read:chats"] - } - ] - } - end - - def show_operation do - %Operation{ - tags: ["Chat administration"], - summary: "Create a chat", - operationId: "AdminAPI.ChatController.show", - parameters: [ - Operation.parameter( - :id, - :path, - :string, - "The id of the chat", - required: true, - example: "1234" - ) - ], - responses: %{ - 200 => - Operation.response( - "The existing chat", - "application/json", - Chat - ) - }, - security: [ - %{ - "oAuth" => ["admin:read"] - } - ] - } - end -end diff --git a/lib/pleroma/web/api_spec/operations/chat_operation.ex b/lib/pleroma/web/api_spec/operations/chat_operation.ex deleted file mode 100644 index 31fd150de..000000000 --- a/lib/pleroma/web/api_spec/operations/chat_operation.ex +++ /dev/null @@ -1,361 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ApiSpec.ChatOperation do - alias OpenApiSpex.Operation - alias OpenApiSpex.Schema - alias Pleroma.Web.ApiSpec.Schemas.ApiError - alias Pleroma.Web.ApiSpec.Schemas.BooleanLike - alias Pleroma.Web.ApiSpec.Schemas.Chat - alias Pleroma.Web.ApiSpec.Schemas.ChatMessage - - import Pleroma.Web.ApiSpec.Helpers - - @spec open_api_operation(atom) :: Operation.t() - def open_api_operation(action) do - operation = String.to_existing_atom("#{action}_operation") - apply(__MODULE__, operation, []) - end - - def mark_as_read_operation do - %Operation{ - tags: ["Chats"], - summary: "Mark all messages in the chat as read", - operationId: "ChatController.mark_as_read", - parameters: [Operation.parameter(:id, :path, :string, "The ID of the Chat")], - requestBody: request_body("Parameters", mark_as_read()), - responses: %{ - 200 => - Operation.response( - "The updated chat", - "application/json", - Chat - ) - }, - security: [ - %{ - "oAuth" => ["write:chats"] - } - ] - } - end - - def mark_message_as_read_operation do - %Operation{ - tags: ["Chats"], - summary: "Mark a message as read", - operationId: "ChatController.mark_message_as_read", - parameters: [ - Operation.parameter(:id, :path, :string, "The ID of the Chat"), - Operation.parameter(:message_id, :path, :string, "The ID of the message") - ], - responses: %{ - 200 => - Operation.response( - "The read ChatMessage", - "application/json", - ChatMessage - ) - }, - security: [ - %{ - "oAuth" => ["write:chats"] - } - ] - } - end - - def show_operation do - %Operation{ - tags: ["Chats"], - summary: "Retrieve a chat", - operationId: "ChatController.show", - parameters: [ - Operation.parameter( - :id, - :path, - :string, - "The id of the chat", - required: true, - example: "1234" - ) - ], - responses: %{ - 200 => - Operation.response( - "The existing chat", - "application/json", - Chat - ) - }, - security: [ - %{ - "oAuth" => ["read"] - } - ] - } - end - - def create_operation do - %Operation{ - tags: ["Chats"], - summary: "Create a chat", - operationId: "ChatController.create", - parameters: [ - Operation.parameter( - :id, - :path, - :string, - "The account id of the recipient of this chat", - required: true, - example: "someflakeid" - ) - ], - responses: %{ - 200 => - Operation.response( - "The created or existing chat", - "application/json", - Chat - ) - }, - security: [ - %{ - "oAuth" => ["write: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() - ], - responses: %{ - 200 => Operation.response("The chats of the user", "application/json", chats_response()) - }, - security: [ - %{ - "oAuth" => ["read:chats"] - } - ] - } - end - - def messages_operation do - %Operation{ - tags: ["Chats"], - summary: "Retrieve chat's messages", - operationId: "ChatController.messages", - parameters: - [Operation.parameter(:id, :path, :string, "The ID of the Chat")] ++ - pagination_params(), - responses: %{ - 200 => - Operation.response( - "The messages in the chat", - "application/json", - chat_messages_response() - ), - 404 => Operation.response("Not Found", "application/json", ApiError) - }, - security: [ - %{ - "oAuth" => ["read:chats"] - } - ] - } - end - - def post_chat_message_operation do - %Operation{ - tags: ["Chats"], - summary: "Post a message to the chat", - operationId: "ChatController.post_chat_message", - parameters: [ - Operation.parameter(:id, :path, :string, "The ID of the Chat") - ], - requestBody: request_body("Parameters", chat_message_create()), - responses: %{ - 200 => - Operation.response( - "The newly created ChatMessage", - "application/json", - ChatMessage - ), - 400 => Operation.response("Bad Request", "application/json", ApiError), - 422 => Operation.response("MRF Rejection", "application/json", ApiError) - }, - security: [ - %{ - "oAuth" => ["write:chats"] - } - ] - } - end - - def delete_message_operation do - %Operation{ - tags: ["Chats"], - summary: "Delete message", - operationId: "ChatController.delete_message", - parameters: [ - Operation.parameter(:id, :path, :string, "The ID of the Chat"), - Operation.parameter(:message_id, :path, :string, "The ID of the message") - ], - responses: %{ - 200 => - Operation.response( - "The deleted ChatMessage", - "application/json", - ChatMessage - ) - }, - security: [ - %{ - "oAuth" => ["write:chats"] - } - ] - } - end - - def chats_response do - %Schema{ - title: "ChatsResponse", - description: "Response schema for multiple Chats", - type: :array, - items: Chat, - example: [ - %{ - "account" => %{ - "pleroma" => %{ - "is_admin" => false, - "is_confirmed" => true, - "hide_followers_count" => false, - "is_moderator" => false, - "hide_favorites" => true, - "ap_id" => "https://dontbulling.me/users/lain", - "hide_follows_count" => false, - "hide_follows" => false, - "background_image" => nil, - "skip_thread_containment" => false, - "hide_followers" => false, - "relationship" => %{}, - "tags" => [] - }, - "avatar" => - "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg", - "following_count" => 0, - "header_static" => "https://originalpatchou.li/images/banner.png", - "source" => %{ - "sensitive" => false, - "note" => "lain", - "pleroma" => %{ - "discoverable" => false, - "actor_type" => "Person" - }, - "fields" => [] - }, - "statuses_count" => 1, - "locked" => false, - "created_at" => "2020-04-16T13:40:15.000Z", - "display_name" => "lain", - "fields" => [], - "acct" => "lain@dontbulling.me", - "id" => "9u6Qw6TAZANpqokMkK", - "emojis" => [], - "avatar_static" => - "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg", - "username" => "lain", - "followers_count" => 0, - "header" => "https://originalpatchou.li/images/banner.png", - "bot" => false, - "note" => "lain", - "url" => "https://dontbulling.me/users/lain" - }, - "id" => "1", - "unread" => 2 - } - ] - } - end - - def chat_messages_response do - %Schema{ - title: "ChatMessagesResponse", - description: "Response schema for multiple ChatMessages", - type: :array, - items: ChatMessage, - example: [ - %{ - "emojis" => [ - %{ - "static_url" => "https://dontbulling.me/emoji/Firefox.gif", - "visible_in_picker" => false, - "shortcode" => "firefox", - "url" => "https://dontbulling.me/emoji/Firefox.gif" - } - ], - "created_at" => "2020-04-21T15:11:46.000Z", - "content" => "Check this out :firefox:", - "id" => "13", - "chat_id" => "1", - "account_id" => "someflakeid", - "unread" => false - }, - %{ - "account_id" => "someflakeid", - "content" => "Whats' up?", - "id" => "12", - "chat_id" => "1", - "emojis" => [], - "created_at" => "2020-04-21T15:06:45.000Z", - "unread" => false - } - ] - } - end - - def chat_message_create do - %Schema{ - title: "ChatMessageCreateRequest", - description: "POST body for creating an chat message", - type: :object, - properties: %{ - content: %Schema{ - type: :string, - description: "The content of your message. Optional if media_id is present" - }, - media_id: %Schema{type: :string, description: "The id of an upload"} - }, - example: %{ - "content" => "Hey wanna buy feet pics?", - "media_id" => "134234" - } - } - end - - def mark_as_read do - %Schema{ - title: "MarkAsReadRequest", - description: "POST body for marking a number of chat messages as read", - type: :object, - required: [:last_read_id], - properties: %{ - last_read_id: %Schema{ - type: :string, - description: "The content of your message." - } - }, - example: %{ - "last_read_id" => "abcdef12456" - } - } - end -end diff --git a/lib/pleroma/web/api_spec/operations/notification_operation.ex b/lib/pleroma/web/api_spec/operations/notification_operation.ex index 01a886de3..b4a20e5e5 100644 --- a/lib/pleroma/web/api_spec/operations/notification_operation.ex +++ b/lib/pleroma/web/api_spec/operations/notification_operation.ex @@ -174,7 +174,6 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do "reblog", "mention", "pleroma:emoji_reaction", - "pleroma:chat_mention", "pleroma:report", "move", "follow_request", @@ -190,7 +189,6 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do - `poll` - A poll you have voted in or created has ended - `move` - Someone moved their account - `pleroma:emoji_reaction` - Someone reacted with emoji to your status - - `pleroma:chat_mention` - Someone mentioned you in a chat message - `pleroma:report` - Someone was reported """ } diff --git a/lib/pleroma/web/api_spec/operations/subscription_operation.ex b/lib/pleroma/web/api_spec/operations/subscription_operation.ex index 60a7fb3b0..a0cf76c32 100644 --- a/lib/pleroma/web/api_spec/operations/subscription_operation.ex +++ b/lib/pleroma/web/api_spec/operations/subscription_operation.ex @@ -142,11 +142,6 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do nullable: true, description: "Receive poll notifications?" }, - "pleroma:chat_mention": %Schema{ - allOf: [BooleanLike], - nullable: true, - description: "Receive chat notifications?" - }, "pleroma:emoji_reaction": %Schema{ allOf: [BooleanLike], nullable: true, @@ -216,11 +211,6 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do nullable: true, description: "Receive poll notifications?" }, - "pleroma:chat_mention": %Schema{ - allOf: [BooleanLike], - nullable: true, - description: "Receive chat notifications?" - }, "pleroma:emoji_reaction": %Schema{ allOf: [BooleanLike], nullable: true, diff --git a/lib/pleroma/web/api_spec/operations/timeline_operation.ex b/lib/pleroma/web/api_spec/operations/timeline_operation.ex index 24d792916..d375c76b8 100644 --- a/lib/pleroma/web/api_spec/operations/timeline_operation.ex +++ b/lib/pleroma/web/api_spec/operations/timeline_operation.ex @@ -43,7 +43,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do tags: ["Timelines"], summary: "Direct timeline", description: - "View statuses with a “direct” scope addressed to the account. Using this endpoint is discouraged, please use [conversations](#tag/Conversations) or [chats](#tag/Chats).", + "View statuses with a “direct” scope addressed to the account. Using this endpoint is discouraged, please use [conversations](#tag/Conversations).", parameters: [with_muted_param() | pagination_params()], security: [%{"oAuth" => ["read:statuses"]}], operationId: "TimelineController.direct", diff --git a/lib/pleroma/web/api_spec/schemas/account.ex b/lib/pleroma/web/api_spec/schemas/account.ex index 548e70544..5d3ac9cd0 100644 --- a/lib/pleroma/web/api_spec/schemas/account.ex +++ b/lib/pleroma/web/api_spec/schemas/account.ex @@ -47,7 +47,6 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do description: "whether the user allows automatically follow moved following accounts" }, background_image: %Schema{type: :string, nullable: true, format: :uri}, - chat_token: %Schema{type: :string}, is_confirmed: %Schema{ type: :boolean, description: @@ -102,7 +101,6 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do description: "A generic map of settings for frontends. Opaque to the backend. Only returned in `verify_credentials` and `update_credentials`" }, - accepts_chat_messages: %Schema{type: :boolean, nullable: true}, favicon: %Schema{ type: :string, format: :uri, @@ -175,9 +173,6 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do "is_admin" => false, "is_moderator" => false, "skip_thread_containment" => false, - "accepts_chat_messages" => true, - "chat_token" => - "SFMyNTY.g3QAAAACZAAEZGF0YW0AAAASOXRLaTNlc2JHN09RZ1oyOTIwZAAGc2lnbmVkbgYARNplS3EB.Mb_Iaqew2bN1I1o79B_iP7encmVCpTKC4OtHZRxdjKc", "unread_conversation_count" => 0, "tags" => [], "notification_settings" => %{ diff --git a/lib/pleroma/web/api_spec/schemas/chat.ex b/lib/pleroma/web/api_spec/schemas/chat.ex deleted file mode 100644 index 4afed910d..000000000 --- a/lib/pleroma/web/api_spec/schemas/chat.ex +++ /dev/null @@ -1,75 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ApiSpec.Schemas.Chat do - alias OpenApiSpex.Schema - alias Pleroma.Web.ApiSpec.Schemas.ChatMessage - - require OpenApiSpex - - OpenApiSpex.schema(%{ - title: "Chat", - description: "Response schema for a Chat", - type: :object, - properties: %{ - id: %Schema{type: :string}, - account: %Schema{type: :object}, - unread: %Schema{type: :integer}, - last_message: ChatMessage, - updated_at: %Schema{type: :string, format: :"date-time"} - }, - example: %{ - "account" => %{ - "pleroma" => %{ - "is_admin" => false, - "is_confirmed" => true, - "hide_followers_count" => false, - "is_moderator" => false, - "hide_favorites" => true, - "ap_id" => "https://dontbulling.me/users/lain", - "hide_follows_count" => false, - "hide_follows" => false, - "background_image" => nil, - "skip_thread_containment" => false, - "hide_followers" => false, - "relationship" => %{}, - "tags" => [] - }, - "avatar" => - "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg", - "following_count" => 0, - "header_static" => "https://originalpatchou.li/images/banner.png", - "source" => %{ - "sensitive" => false, - "note" => "lain", - "pleroma" => %{ - "discoverable" => false, - "actor_type" => "Person" - }, - "fields" => [] - }, - "statuses_count" => 1, - "is_locked" => false, - "created_at" => "2020-04-16T13:40:15.000Z", - "display_name" => "lain", - "fields" => [], - "acct" => "lain@dontbulling.me", - "id" => "9u6Qw6TAZANpqokMkK", - "emojis" => [], - "avatar_static" => - "https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg", - "username" => "lain", - "followers_count" => 0, - "header" => "https://originalpatchou.li/images/banner.png", - "bot" => false, - "note" => "lain", - "url" => "https://dontbulling.me/users/lain" - }, - "id" => "1", - "unread" => 2, - "last_message" => ChatMessage.schema().example(), - "updated_at" => "2020-04-21T15:06:45.000Z" - } - }) -end diff --git a/lib/pleroma/web/api_spec/schemas/chat_message.ex b/lib/pleroma/web/api_spec/schemas/chat_message.ex deleted file mode 100644 index 348fe95f8..000000000 --- a/lib/pleroma/web/api_spec/schemas/chat_message.ex +++ /dev/null @@ -1,77 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ApiSpec.Schemas.ChatMessage do - alias OpenApiSpex.Schema - alias Pleroma.Web.ApiSpec.Schemas.Emoji - - require OpenApiSpex - - OpenApiSpex.schema(%{ - title: "ChatMessage", - description: "Response schema for a ChatMessage", - nullable: true, - type: :object, - properties: %{ - id: %Schema{type: :string}, - account_id: %Schema{type: :string, description: "The Mastodon API id of the actor"}, - chat_id: %Schema{type: :string}, - content: %Schema{type: :string, nullable: true}, - created_at: %Schema{type: :string, format: :"date-time"}, - emojis: %Schema{type: :array, items: Emoji}, - attachment: %Schema{type: :object, nullable: true}, - card: %Schema{ - type: :object, - nullable: true, - description: "Preview card for links included within status content", - required: [:url, :title, :description, :type], - properties: %{ - type: %Schema{ - type: :string, - enum: ["link", "photo", "video", "rich"], - description: "The type of the preview card" - }, - provider_name: %Schema{ - type: :string, - nullable: true, - description: "The provider of the original resource" - }, - provider_url: %Schema{ - type: :string, - format: :uri, - description: "A link to the provider of the original resource" - }, - url: %Schema{type: :string, format: :uri, description: "Location of linked resource"}, - image: %Schema{ - type: :string, - nullable: true, - format: :uri, - description: "Preview thumbnail" - }, - 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", - "chat_id" => "1", - "content" => "hey you again", - "created_at" => "2020-04-21T15:06:45.000Z", - "card" => nil, - "emojis" => [ - %{ - "static_url" => "https://dontbulling.me/emoji/Firefox.gif", - "visible_in_picker" => false, - "shortcode" => "firefox", - "url" => "https://dontbulling.me/emoji/Firefox.gif" - } - ], - "id" => "14", - "attachment" => nil, - "unread" => false - } - }) -end diff --git a/lib/pleroma/web/channels/user_socket.ex b/lib/pleroma/web/channels/user_socket.ex deleted file mode 100644 index 043206835..000000000 --- a/lib/pleroma/web/channels/user_socket.ex +++ /dev/null @@ -1,45 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.UserSocket do - use Phoenix.Socket - alias Pleroma.User - - ## Channels - # channel "room:*", Pleroma.Web.RoomChannel - channel("chat:*", Pleroma.Web.ShoutChannel) - - # Socket params are passed from the client and can - # be used to verify and authenticate a user. After - # verification, you can put default assigns into - # the socket that will be set for all channels, ie - # - # {:ok, assign(socket, :user_id, verified_user_id)} - # - # To deny connection, return `:error`. - # - # See `Phoenix.Token` documentation for examples in - # performing token verification on connect. - def connect(%{"token" => token}, socket) do - with true <- Pleroma.Config.get([:shout, :enabled]), - {:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84_600), - %User{} = user <- Pleroma.User.get_cached_by_id(user_id) do - {:ok, assign(socket, :user_name, user.nickname)} - else - _e -> :error - end - end - - # Socket id's are topics that allow you to identify all sockets for a given user: - # - # def id(socket), do: "user_socket:#{socket.assigns.user_id}" - # - # Would allow you to broadcast a "disconnect" event and terminate - # all active sockets and channels for a given user: - # - # Pleroma.Web.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{}) - # - # Returning `nil` makes this socket anonymous. - def id(_socket), do: nil -end diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex index 3c2e7ae86..8ab50cf2b 100644 --- a/lib/pleroma/web/common_api.ex +++ b/lib/pleroma/web/common_api.ex @@ -5,7 +5,6 @@ defmodule Pleroma.Web.CommonAPI do alias Pleroma.Activity alias Pleroma.Conversation.Participation - alias Pleroma.Formatter alias Pleroma.Object alias Pleroma.ThreadMute alias Pleroma.User @@ -30,57 +29,6 @@ defmodule Pleroma.Web.CommonAPI do end end - def post_chat_message(%User{} = user, %User{} = recipient, content, opts \\ []) do - with maybe_attachment <- opts[:media_id] && Object.get_by_id(opts[:media_id]), - :ok <- validate_chat_content_length(content, !!maybe_attachment), - {_, {:ok, chat_message_data, _meta}} <- - {:build_object, - Builder.chat_message( - user, - recipient.ap_id, - content |> format_chat_content, - attachment: maybe_attachment - )}, - {_, {:ok, create_activity_data, _meta}} <- - {:build_create_activity, Builder.create(user, chat_message_data, [recipient.ap_id])}, - {_, {:ok, %Activity{} = activity, _meta}} <- - {:common_pipeline, - Pipeline.common_pipeline(create_activity_data, - local: true, - idempotency_key: opts[:idempotency_key] - )} do - {:ok, activity} - else - {:common_pipeline, {:reject, _} = e} -> e - e -> e - end - end - - defp format_chat_content(nil), do: nil - - defp format_chat_content(content) do - {text, _, _} = - content - |> Formatter.html_escape("text/plain") - |> Formatter.linkify() - |> (fn {text, mentions, tags} -> - {String.replace(text, ~r/\r?\n/, "
"), mentions, tags} - end).() - - text - end - - defp validate_chat_content_length(_, true), do: :ok - defp validate_chat_content_length(nil, false), do: {:error, :no_content} - - defp validate_chat_content_length(content, _) do - if String.length(content) <= Pleroma.Config.get([:instance, :chat_limit]) do - :ok - else - {:error, :content_too_long} - end - end - def unblock(blocker, blocked) do with {_, %Activity{} = block} <- {:fetch_block, Utils.fetch_latest_block(blocker, blocked)}, {:ok, unblock_data, _} <- Builder.undo(blocker, block), diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 62a6459b1..2e7e9692e 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -9,7 +9,6 @@ defmodule Pleroma.Web.Endpoint do alias Pleroma.Config - socket("/socket", Pleroma.Web.UserSocket) socket("/live", Phoenix.LiveView.Socket) plug(Pleroma.Web.Plugs.SetLocalePlug) diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 83cebbb96..ed7fb802a 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -153,13 +153,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do @doc "GET /api/v1/accounts/verify_credentials" def verify_credentials(%{assigns: %{user: user}} = conn, _) do - chat_token = Phoenix.Token.sign(conn, "user socket", user.id) - render(conn, "show.json", user: user, for: user, - with_pleroma_settings: true, - with_chat_token: chat_token + with_pleroma_settings: true ) end @@ -188,8 +185,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do :show_role, :skip_thread_containment, :allow_following_move, - :also_known_as, - :accepts_chat_messages + :also_known_as ] |> Enum.reduce(%{}, fn key, acc -> Maps.put_if_present(acc, key, params[key], &{:ok, Params.truthy_param?(&1)}) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 4b15b1635..06acf0a26 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -289,7 +289,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do relationship: relationship, skip_thread_containment: user.skip_thread_containment, background_image: image_url(user.background) |> MediaProxy.url(), - accepts_chat_messages: user.accepts_chat_messages, favicon: favicon } } @@ -297,7 +296,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do |> maybe_put_settings(user, opts[:for], opts) |> maybe_put_notification_settings(user, opts[:for]) |> maybe_put_settings_store(user, opts[:for], opts) - |> maybe_put_chat_token(user, opts[:for], opts) |> maybe_put_activation_status(user, opts[:for]) |> maybe_put_follow_requests_count(user, opts[:for]) |> maybe_put_allow_following_move(user, opts[:for]) @@ -350,15 +348,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do defp maybe_put_settings_store(data, _, _, _), do: data - defp maybe_put_chat_token(data, %User{id: id}, %User{id: id}, %{ - with_chat_token: token - }) do - data - |> Kernel.put_in([:pleroma, :chat_token], token) - end - - defp maybe_put_chat_token(data, _, _, _), do: data - defp maybe_put_role(data, %User{show_role: true} = user, _) do data |> Kernel.put_in([:pleroma, :is_admin], user.is_admin) diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index d67f100a6..4cfa8d85c 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -37,7 +37,6 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do background_upload_limit: Keyword.get(instance, :background_upload_limit), banner_upload_limit: Keyword.get(instance, :banner_upload_limit), background_image: Pleroma.Web.Endpoint.url() <> Keyword.get(instance, :background_image), - shout_limit: Config.get([:shout, :limit]), description_limit: Keyword.get(instance, :description_limit), pleroma: %{ metadata: %{ diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex index bb156799e..83914a275 100644 --- a/lib/pleroma/web/mastodon_api/views/notification_view.ex +++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex @@ -6,9 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do use Pleroma.Web, :view alias Pleroma.Activity - alias Pleroma.Chat.MessageReference alias Pleroma.Notification - alias Pleroma.Object alias Pleroma.User alias Pleroma.UserRelationship alias Pleroma.Web.AdminAPI.Report @@ -18,7 +16,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.NotificationView alias Pleroma.Web.MastodonAPI.StatusView - alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView @parent_types ~w{Like Announce EmojiReact} @@ -121,9 +118,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do |> put_status(parent_activity_fn.(), reading_user, status_render_opts) |> put_emoji(activity) - "pleroma:chat_mention" -> - put_chat_message(response, activity, reading_user, status_render_opts) - "pleroma:report" -> put_report(response, activity) @@ -144,17 +138,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do |> Map.put(:emoji_url, MediaProxy.url(Pleroma.Emoji.emoji_url(activity.data))) end - defp put_chat_message(response, activity, reading_user, opts) do - object = Object.normalize(activity, fetch: false) - author = User.get_cached_by_ap_id(object.data["actor"]) - chat = Pleroma.Chat.get(reading_user.id, author.ap_id) - cm_ref = MessageReference.for_chat_and_object(chat, object) - render_opts = Map.merge(opts, %{for: reading_user, chat_message_reference: cm_ref}) - chat_message_render = MessageReferenceView.render("show.json", render_opts) - - Map.put(response, :chat_message, chat_message_render) - end - defp put_status(response, activity, reading_user, opts) do status_render_opts = Map.merge(opts, %{activity: activity, for: reading_user}) status_render = StatusView.render("show.json", status_render_opts) diff --git a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex deleted file mode 100644 index 669d50132..000000000 --- a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex +++ /dev/null @@ -1,188 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.Web.PleromaAPI.ChatController do - use Pleroma.Web, :controller - - import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2] - - alias Pleroma.Activity - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.Object - alias Pleroma.Pagination - alias Pleroma.Repo - alias Pleroma.User - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView - alias Pleroma.Web.Plugs.OAuthScopesPlug - - import Ecto.Query - - action_fallback(Pleroma.Web.MastodonAPI.FallbackController) - - plug( - OAuthScopesPlug, - %{scopes: ["write:chats"]} - when action in [ - :post_chat_message, - :create, - :mark_as_read, - :mark_message_as_read, - :delete_message - ] - ) - - plug( - OAuthScopesPlug, - %{scopes: ["read:chats"]} when action in [:messages, :index, :index2, :show] - ) - - plug(Pleroma.Web.ApiSpec.CastAndValidate) - - defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ChatOperation - - def delete_message(%{assigns: %{user: %{id: user_id} = user}} = conn, %{ - message_id: message_id, - id: chat_id - }) do - with %MessageReference{} = cm_ref <- - MessageReference.get_by_id(message_id), - ^chat_id <- to_string(cm_ref.chat_id), - %Chat{user_id: ^user_id} <- Chat.get_by_id(chat_id), - {:ok, _} <- remove_or_delete(cm_ref, user) do - conn - |> put_view(MessageReferenceView) - |> render("show.json", chat_message_reference: cm_ref) - else - _e -> - {:error, :could_not_delete} - end - end - - defp remove_or_delete( - %{object: %{data: %{"actor" => actor, "id" => id}}}, - %{ap_id: actor} = user - ) do - with %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do - CommonAPI.delete(activity.id, user) - end - end - - defp remove_or_delete(cm_ref, _), do: MessageReference.delete(cm_ref) - - def post_chat_message( - %{body_params: params, assigns: %{user: user}} = conn, - %{id: id} - ) do - with {:ok, chat} <- Chat.get_by_user_and_id(user, id), - %User{} = recipient <- User.get_cached_by_ap_id(chat.recipient), - {:ok, activity} <- - CommonAPI.post_chat_message(user, recipient, params[:content], - media_id: params[:media_id], - idempotency_key: idempotency_key(conn) - ), - message <- Object.normalize(activity, fetch: false), - cm_ref <- MessageReference.for_chat_and_object(chat, message) do - conn - |> put_view(MessageReferenceView) - |> render("show.json", chat_message_reference: cm_ref) - else - {:reject, message} -> - conn - |> put_status(:unprocessable_entity) - |> json(%{error: message}) - - {:error, message} -> - conn - |> put_status(:bad_request) - |> json(%{error: message}) - end - end - - def mark_message_as_read( - %{assigns: %{user: %{id: user_id}}} = conn, - %{id: chat_id, message_id: message_id} - ) do - with %MessageReference{} = cm_ref <- MessageReference.get_by_id(message_id), - ^chat_id <- to_string(cm_ref.chat_id), - %Chat{user_id: ^user_id} <- Chat.get_by_id(chat_id), - {:ok, cm_ref} <- MessageReference.mark_as_read(cm_ref) do - conn - |> put_view(MessageReferenceView) - |> render("show.json", chat_message_reference: cm_ref) - end - end - - def mark_as_read( - %{body_params: %{last_read_id: last_read_id}, assigns: %{user: user}} = conn, - %{id: id} - ) do - with {:ok, chat} <- Chat.get_by_user_and_id(user, id), - {_n, _} <- MessageReference.set_all_seen_for_chat(chat, last_read_id) do - render(conn, "show.json", chat: chat) - end - end - - def messages(%{assigns: %{user: user}} = conn, %{id: id} = params) do - with {:ok, chat} <- Chat.get_by_user_and_id(user, id) do - chat_message_refs = - chat - |> MessageReference.for_chat_query() - |> Pagination.fetch_paginated(params) - - conn - |> add_link_headers(chat_message_refs) - |> put_view(MessageReferenceView) - |> render("index.json", chat_message_references: chat_message_refs) - end - end - - 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) - - conn - |> add_link_headers(chats) - |> render("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) - - user_id - |> Chat.for_user_query() - |> where([c], c.recipient not in ^exclude_users) - end - - def create(%{assigns: %{user: user}} = conn, %{id: id}) do - with %User{ap_id: recipient} <- User.get_cached_by_id(id), - {:ok, %Chat{} = chat} <- Chat.get_or_create(user.id, recipient) do - render(conn, "show.json", chat: chat) - end - end - - def show(%{assigns: %{user: user}} = conn, %{id: id}) do - with {:ok, chat} <- Chat.get_by_user_and_id(user, id) do - render(conn, "show.json", chat: chat) - end - end - - defp idempotency_key(conn) do - case get_req_header(conn, "idempotency-key") do - [key] -> key - _ -> nil - end - end -end diff --git a/lib/pleroma/web/pleroma_api/views/chat/message_reference_view.ex b/lib/pleroma/web/pleroma_api/views/chat/message_reference_view.ex deleted file mode 100644 index 2e4355992..000000000 --- a/lib/pleroma/web/pleroma_api/views/chat/message_reference_view.ex +++ /dev/null @@ -1,63 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.PleromaAPI.Chat.MessageReferenceView do - use Pleroma.Web, :view - - alias Pleroma.Maps - alias Pleroma.User - alias Pleroma.Web.CommonAPI.Utils - alias Pleroma.Web.MastodonAPI.StatusView - - @cachex Pleroma.Config.get([:cachex, :provider], Cachex) - - def render( - "show.json", - %{ - chat_message_reference: %{ - id: id, - object: %{data: chat_message} = object, - chat_id: chat_id, - unread: unread - } - } - ) do - %{ - id: id |> to_string(), - content: chat_message["content"], - chat_id: chat_id |> to_string(), - account_id: User.get_cached_by_ap_id(chat_message["actor"]).id, - created_at: Utils.to_masto_date(chat_message["published"]), - emojis: StatusView.build_emojis(chat_message["emoji"]), - attachment: - chat_message["attachment"] && - StatusView.render("attachment.json", attachment: chat_message["attachment"]), - unread: unread, - card: - StatusView.render( - "card.json", - Pleroma.Web.RichMedia.Helpers.fetch_data_for_object(object) - ) - } - |> put_idempotency_key() - end - - def render("index.json", opts) do - render_many( - opts[:chat_message_references], - __MODULE__, - "show.json", - Map.put(opts, :as, :chat_message_reference) - ) - end - - defp put_idempotency_key(data) do - with {:ok, idempotency_key} <- @cachex.get(:chat_message_id_idempotency_key_cache, data.id) do - data - |> Maps.put_if_present(:idempotency_key, idempotency_key) - else - _ -> data - end - end -end diff --git a/lib/pleroma/web/pleroma_api/views/chat_view.ex b/lib/pleroma/web/pleroma_api/views/chat_view.ex deleted file mode 100644 index 3794818a7..000000000 --- a/lib/pleroma/web/pleroma_api/views/chat_view.ex +++ /dev/null @@ -1,44 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.PleromaAPI.ChatView do - use Pleroma.Web, :view - - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.User - alias Pleroma.Web.CommonAPI.Utils - alias Pleroma.Web.MastodonAPI.AccountView - alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView - - def render("show.json", %{chat: %Chat{} = chat} = opts) do - recipient = User.get_cached_by_ap_id(chat.recipient) - last_message = opts[:last_message] || MessageReference.last_message_for_chat(chat) - account_view_opts = account_view_opts(opts, recipient) - - %{ - id: chat.id |> to_string(), - account: AccountView.render("show.json", account_view_opts), - unread: MessageReference.unread_count_for_chat(chat), - last_message: - last_message && - MessageReferenceView.render("show.json", chat_message_reference: last_message), - updated_at: Utils.to_masto_date(chat.updated_at) - } - end - - def render("index.json", %{chats: chats} = opts) do - render_many(chats, __MODULE__, "show.json", Map.delete(opts, :chats)) - end - - defp account_view_opts(opts, recipient) do - account_view_opts = Map.put(opts, :user, recipient) - - if Map.has_key?(account_view_opts, :for) do - account_view_opts - else - Map.put(account_view_opts, :skip_visibility_check, true) - end - end -end diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 28e13ef9c..c30a39e94 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -124,13 +124,6 @@ defmodule Pleroma.Web.Push.Impl do def format_body(activity, actor, object, mastodon_type \\ nil) - def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}, _) do - case data["content"] do - nil -> "@#{actor.nickname}: (Attachment)" - content -> "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" - end - end - def format_body( %{activity: %{data: %{"type" => "Create"}}}, actor, @@ -187,7 +180,6 @@ defmodule Pleroma.Web.Push.Impl do "follow_request" -> "New Follow Request" "reblog" -> "New Repeat" "favourite" -> "New Favorite" - "pleroma:chat_mention" -> "New Chat Message" "pleroma:emoji_reaction" -> "New Reaction" type -> "New #{String.capitalize(type || "event")}" end diff --git a/lib/pleroma/web/push/subscription.ex b/lib/pleroma/web/push/subscription.ex index 35bf2e223..b063b103f 100644 --- a/lib/pleroma/web/push/subscription.ex +++ b/lib/pleroma/web/push/subscription.ex @@ -26,7 +26,7 @@ defmodule Pleroma.Web.Push.Subscription do end # credo:disable-for-next-line Credo.Check.Readability.MaxLineLength - @supported_alert_types ~w[follow favourite mention reblog poll pleroma:chat_mention pleroma:emoji_reaction]a + @supported_alert_types ~w[follow favourite mention reblog poll pleroma:emoji_reaction]a defp alerts(%{data: %{alerts: alerts}}) do alerts = Map.take(alerts, @supported_alert_types) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 8a53f770e..d413835bb 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -253,12 +253,8 @@ defmodule Pleroma.Web.Router do patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials) get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses) - get("/users/:nickname/chats", AdminAPIController, :list_user_chats) get("/statuses", StatusController, :index) - - get("/chats/:id", ChatController, :show) - get("/chats/:id/messages", ChatController, :messages) end # AdminAPI: admins and mods (staff) can perform these actions @@ -298,8 +294,6 @@ defmodule Pleroma.Web.Router do post("/reload_emoji", AdminAPIController, :reload_emoji) get("/stats", AdminAPIController, :stats) - - delete("/chats/:id/messages/:message_id", ChatController, :delete_message) end scope "/api/v1/pleroma/emoji", Pleroma.Web.PleromaAPI do @@ -427,14 +421,6 @@ defmodule Pleroma.Web.Router do scope [] do pipe_through(:authenticated_api) - post("/chats/by-account-id/:id", ChatController, :create) - get("/chats/:id", ChatController, :show) - get("/chats/:id/messages", ChatController, :messages) - post("/chats/:id/messages", ChatController, :post_chat_message) - delete("/chats/:id/messages/:message_id", ChatController, :delete_message) - post("/chats/:id/read", ChatController, :mark_as_read) - post("/chats/:id/messages/:message_id/read", ChatController, :mark_message_as_read) - get("/conversations/:id/statuses", ConversationController, :statuses) get("/conversations/:id", ConversationController, :show) post("/conversations/read", ConversationController, :mark_as_read) @@ -471,13 +457,6 @@ 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) diff --git a/lib/pleroma/web/shout_channel.ex b/lib/pleroma/web/shout_channel.ex deleted file mode 100644 index 17caecb1a..000000000 --- a/lib/pleroma/web/shout_channel.ex +++ /dev/null @@ -1,59 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ShoutChannel do - use Phoenix.Channel - - alias Pleroma.User - alias Pleroma.Web.MastodonAPI.AccountView - alias Pleroma.Web.ShoutChannel.ShoutChannelState - - def join("chat:public", _message, socket) do - send(self(), :after_join) - {:ok, socket} - end - - def handle_info(:after_join, socket) do - push(socket, "messages", %{messages: ShoutChannelState.messages()}) - {:noreply, socket} - end - - def handle_in("new_msg", %{"text" => text}, %{assigns: %{user_name: user_name}} = socket) do - text = String.trim(text) - - if String.length(text) in 1..Pleroma.Config.get([:shout, :limit]) do - author = User.get_cached_by_nickname(user_name) - author_json = AccountView.render("show.json", user: author, skip_visibility_check: true) - - message = ShoutChannelState.add_message(%{text: text, author: author_json}) - - broadcast!(socket, "new_msg", message) - end - - {:noreply, socket} - end -end - -defmodule Pleroma.Web.ShoutChannel.ShoutChannelState do - use Agent - - @max_messages 20 - - def start_link(_) do - Agent.start_link(fn -> %{max_id: 1, messages: []} end, name: __MODULE__) - end - - def add_message(message) do - Agent.get_and_update(__MODULE__, fn state -> - id = state[:max_id] + 1 - message = Map.put(message, "id", id) - messages = [message | state[:messages]] |> Enum.take(@max_messages) - {message, %{max_id: id, messages: messages}} - end) - end - - def messages do - Agent.get(__MODULE__, fn state -> state[:messages] |> Enum.reverse() end) - end -end diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index fc3bbb130..9a4ac1317 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -6,7 +6,6 @@ defmodule Pleroma.Web.Streamer do require Logger alias Pleroma.Activity - alias Pleroma.Chat.MessageReference alias Pleroma.Config alias Pleroma.Conversation.Participation alias Pleroma.Notification @@ -25,7 +24,7 @@ defmodule Pleroma.Web.Streamer do def registry, do: @registry @public_streams ["public", "public:local", "public:media", "public:local:media"] - @user_streams ["user", "user:notification", "direct", "user:pleroma_chat"] + @user_streams ["user", "user:notification", "direct"] @doc "Expands and authorizes a stream, and registers the process for streaming." @spec get_topic_and_add_socket( @@ -241,19 +240,6 @@ defmodule Pleroma.Web.Streamer do end) end - defp do_stream(topic, {user, %MessageReference{} = cm_ref}) - when topic in ["user", "user:pleroma_chat"] do - topic = "#{topic}:#{user.id}" - - text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}) - - Registry.dispatch(@registry, topic, fn list -> - Enum.each(list, fn {pid, _auth} -> - send(pid, {:text, text}) - end) - end) - end - defp do_stream("user", item) do Logger.debug("Trying to push to users") diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex index 7706035e9..de2e4d1e9 100644 --- a/lib/pleroma/web/views/streamer_view.ex +++ b/lib/pleroma/web/views/streamer_view.ex @@ -51,29 +51,6 @@ defmodule Pleroma.Web.StreamerView do |> Jason.encode!() end - def render("chat_update.json", %{chat_message_reference: cm_ref}) do - # Explicitly giving the cmr for the object here, so we don't accidentally - # send a later 'last_message' that was inserted between inserting this and - # streaming it out - # - # It also contains the chat with a cache of the correct unread count - Logger.debug("Trying to stream out #{inspect(cm_ref)}") - - representation = - Pleroma.Web.PleromaAPI.ChatView.render( - "show.json", - %{last_message: cm_ref, chat: cm_ref.chat} - ) - - %{ - event: "pleroma:chat_update", - payload: - representation - |> Jason.encode!() - } - |> Jason.encode!() - end - def render("follow_relationships_update.json", item) do %{ event: "pleroma:follow_relationships_update", diff --git a/test/fixtures/mewmew_no_name.json b/test/fixtures/mewmew_no_name.json index 532d4cf70..08e245254 100644 --- a/test/fixtures/mewmew_no_name.json +++ b/test/fixtures/mewmew_no_name.json @@ -8,7 +8,6 @@ ], "attachment" : [], "capabilities" : { - "acceptsChatMessages" : true }, "discoverable" : false, "endpoints" : { diff --git a/test/mix/tasks/pleroma/config_test.exs b/test/mix/tasks/pleroma/config_test.exs index 2b8252db7..d5e038bee 100644 --- a/test/mix/tasks/pleroma/config_test.exs +++ b/test/mix/tasks/pleroma/config_test.exs @@ -129,7 +129,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do notify_email: "noreply@example.com", description: "A Pleroma instance, an alternative fediverse server", limit: 5_000, - chat_limit: 5_000, remote_limit: 100_000, upload_limit: 16_000_000, avatar_upload_limit: 2_000_000, @@ -189,7 +188,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do {:ok, file} = File.read(temp_file) assert file == - "import Config\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n" + "import Config\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n" end end diff --git a/test/pleroma/chat/message_reference_test.exs b/test/pleroma/chat/message_reference_test.exs deleted file mode 100644 index c8db3b450..000000000 --- a/test/pleroma/chat/message_reference_test.exs +++ /dev/null @@ -1,29 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Chat.MessageReferenceTest do - use Pleroma.DataCase, async: true - - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.Web.CommonAPI - - import Pleroma.Factory - - describe "messages" do - test "it returns the last message in a chat" do - user = insert(:user) - recipient = insert(:user) - - {:ok, _message_1} = CommonAPI.post_chat_message(user, recipient, "hey") - {:ok, _message_2} = CommonAPI.post_chat_message(recipient, user, "ho") - - {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id) - - message = MessageReference.last_message_for_chat(chat) - - assert message.object.data["content"] == "ho" - end - end -end diff --git a/test/pleroma/chat_test.exs b/test/pleroma/chat_test.exs deleted file mode 100644 index a5fd1e02e..000000000 --- a/test/pleroma/chat_test.exs +++ /dev/null @@ -1,84 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.ChatTest do - use Pleroma.DataCase, async: true - - alias Pleroma.Chat - - import Pleroma.Factory - - describe "creation and getting" do - test "it only works if the recipient is a valid user (for now)" do - user = insert(:user) - - assert {:error, _chat} = Chat.bump_or_create(user.id, "http://some/nonexisting/account") - assert {:error, _chat} = Chat.get_or_create(user.id, "http://some/nonexisting/account") - end - - test "it creates a chat for a user and recipient" do - user = insert(:user) - other_user = insert(:user) - - {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id) - - assert chat.id - end - - test "deleting the user deletes the chat" do - user = insert(:user) - other_user = insert(:user) - - {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id) - - Repo.delete(user) - - refute Chat.get_by_id(chat.id) - end - - test "deleting the recipient deletes the chat" do - user = insert(:user) - other_user = insert(:user) - - {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id) - - Repo.delete(other_user) - - refute Chat.get_by_id(chat.id) - end - - test "it returns and bumps a chat for a user and recipient if it already exists" do - user = insert(:user) - other_user = insert(:user) - - {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id) - {:ok, chat_two} = Chat.bump_or_create(user.id, other_user.ap_id) - - assert chat.id == chat_two.id - end - - test "it returns a chat for a user and recipient if it already exists" do - user = insert(:user) - other_user = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - {:ok, chat_two} = Chat.get_or_create(user.id, other_user.ap_id) - - assert chat.id == chat_two.id - end - - test "a returning chat will have an updated `update_at` field" do - user = insert(:user) - other_user = insert(:user) - - {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id) - {:ok, chat} = time_travel(chat, -2) - - {:ok, chat_two} = Chat.bump_or_create(user.id, other_user.ap_id) - - assert chat.id == chat_two.id - assert chat.updated_at != chat_two.updated_at - end - end -end diff --git a/test/pleroma/config/deprecation_warnings_test.exs b/test/pleroma/config/deprecation_warnings_test.exs index 12597506b..053e28207 100644 --- a/test/pleroma/config/deprecation_warnings_test.exs +++ b/test/pleroma/config/deprecation_warnings_test.exs @@ -279,14 +279,4 @@ defmodule Pleroma.Config.DeprecationWarningsTest do end) =~ "Your config is using the old setting for controlling the URL of media uploaded to your S3 bucket." end - - test "check_old_chat_shoutbox/0" do - clear_config([:instance, :chat_limit], 1_000) - clear_config([:chat, :enabled], true) - - assert capture_log(fn -> - DeprecationWarnings.check_old_chat_shoutbox() - end) =~ - "Your config is using the old namespace for the Shoutbox configuration." - end end diff --git a/test/pleroma/config/transfer_task_test.exs b/test/pleroma/config/transfer_task_test.exs index 9e3f11f1a..c56f20ec5 100644 --- a/test/pleroma/config/transfer_task_test.exs +++ b/test/pleroma/config/transfer_task_test.exs @@ -95,8 +95,8 @@ defmodule Pleroma.Config.TransferTaskTest do @tag :erratic test "on reboot time key" do - clear_config(:shout) - insert(:config, key: :shout, value: [enabled: false]) + clear_config([:pleroma, :rate_limit]) + insert(:config, key: {:pleroma, :rate_limit}, value: [enabled: false]) assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted" end @@ -109,10 +109,10 @@ defmodule Pleroma.Config.TransferTaskTest do @tag :erratic test "don't restart pleroma on reboot time key and subkey if there is false flag" do - clear_config(:shout) + clear_config([:pleroma, :rate_limit]) clear_config(Pleroma.Captcha) - insert(:config, key: :shout, value: [enabled: false]) + insert(:config, key: {:pleroma, :rate_limit}, value: [enabled: false]) insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60]) refute String.contains?( diff --git a/test/pleroma/migration_helper/notification_backfill_test.exs b/test/pleroma/migration_helper/notification_backfill_test.exs index fd253b530..eca060800 100644 --- a/test/pleroma/migration_helper/notification_backfill_test.exs +++ b/test/pleroma/migration_helper/notification_backfill_test.exs @@ -19,7 +19,6 @@ defmodule Pleroma.MigrationHelper.NotificationBackfillTest do other_user = insert(:user) {:ok, post} = CommonAPI.post(user, %{status: "yeah, @#{other_user.nickname}"}) - {:ok, chat} = CommonAPI.post_chat_message(user, other_user, "yo") {:ok, react} = CommonAPI.react_with_emoji(post.id, other_user, "☕") {:ok, like} = CommonAPI.favorite(other_user, post.id) {:ok, react_2} = CommonAPI.react_with_emoji(post.id, other_user, "☕") @@ -33,7 +32,7 @@ defmodule Pleroma.MigrationHelper.NotificationBackfillTest do |> Activity.change(%{data: data}) |> Repo.update() - assert {5, nil} = Repo.update_all(Notification, set: [type: nil]) + assert {4, nil} = Repo.update_all(Notification, set: [type: nil]) NotificationBackfill.fill_in_notification_types() @@ -48,9 +47,6 @@ defmodule Pleroma.MigrationHelper.NotificationBackfillTest do assert %{type: "pleroma:emoji_reaction"} = Repo.get_by(Notification, user_id: user.id, activity_id: react_2.id) - - assert %{type: "pleroma:chat_mention"} = - Repo.get_by(Notification, user_id: other_user.id, activity_id: chat.id) end end end diff --git a/test/pleroma/repo/migrations/rename_instance_chat_test.exs b/test/pleroma/repo/migrations/rename_instance_chat_test.exs deleted file mode 100644 index acd45600c..000000000 --- a/test/pleroma/repo/migrations/rename_instance_chat_test.exs +++ /dev/null @@ -1,52 +0,0 @@ -defmodule Pleroma.Repo.Migrations.RenameInstanceChatTest do - use Pleroma.DataCase - import Pleroma.Factory - import Pleroma.Tests.Helpers - alias Pleroma.ConfigDB - - setup do: clear_config([:instance]) - setup do: clear_config([:chat]) - setup_all do: require_migration("20200806175913_rename_instance_chat") - - describe "up/0" do - test "migrates chat settings to shout", %{migration: migration} do - insert(:config, group: :pleroma, key: :instance, value: [chat_limit: 6000]) - insert(:config, group: :pleroma, key: :chat, value: [enabled: true]) - - assert migration.up() == :ok - - assert ConfigDB.get_by_params(%{group: :pleroma, key: :chat}) == nil - assert ConfigDB.get_by_params(%{group: :pleroma, key: :instance}) == nil - - assert ConfigDB.get_by_params(%{group: :pleroma, key: :shout}).value == [ - limit: 6000, - enabled: true - ] - end - - test "does nothing when chat settings are not set", %{migration: migration} do - assert migration.up() == :noop - assert ConfigDB.get_by_params(%{group: :pleroma, key: :chat}) == nil - assert ConfigDB.get_by_params(%{group: :pleroma, key: :shout}) == nil - end - end - - describe "down/0" do - test "migrates shout settings back to instance and chat", %{migration: migration} do - insert(:config, group: :pleroma, key: :shout, value: [limit: 42, enabled: true]) - - assert migration.down() == :ok - - assert ConfigDB.get_by_params(%{group: :pleroma, key: :chat}).value == [enabled: true] - assert ConfigDB.get_by_params(%{group: :pleroma, key: :instance}).value == [chat_limit: 42] - assert ConfigDB.get_by_params(%{group: :pleroma, key: :shout}) == nil - end - - test "does nothing when shout settings are not set", %{migration: migration} do - assert migration.down() == :noop - assert ConfigDB.get_by_params(%{group: :pleroma, key: :chat}) == nil - assert ConfigDB.get_by_params(%{group: :pleroma, key: :instance}) == nil - assert ConfigDB.get_by_params(%{group: :pleroma, key: :shout}) == nil - end - end -end diff --git a/test/pleroma/user/welcome_chat_message_test.exs b/test/pleroma/user/welcome_chat_message_test.exs deleted file mode 100644 index 42a45fa19..000000000 --- a/test/pleroma/user/welcome_chat_message_test.exs +++ /dev/null @@ -1,36 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.User.WelcomeChatMessageTest do - use Pleroma.DataCase - - alias Pleroma.User.WelcomeChatMessage - - import Pleroma.Factory - - setup do: clear_config([:welcome]) - - describe "post_message/1" do - test "send a chat welcome message" do - welcome_user = insert(:user, name: "mewmew") - user = insert(:user) - - clear_config([:welcome, :chat_message, :enabled], true) - clear_config([:welcome, :chat_message, :sender_nickname], welcome_user.nickname) - - clear_config( - [:welcome, :chat_message, :message], - "Hello, welcome to Blob/Cat!" - ) - - {:ok, %Pleroma.Activity{} = activity} = WelcomeChatMessage.post_message(user) - - assert user.ap_id in activity.recipients - assert Pleroma.Object.normalize(activity, fetch: false).data["type"] == "ChatMessage" - - assert Pleroma.Object.normalize(activity, fetch: false).data["content"] == - "Hello, welcome to Blob/Cat!" - end - end -end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 8486987fd..dee76f676 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -443,22 +443,6 @@ defmodule Pleroma.UserTest do assert activity.actor == welcome_user.ap_id end - test "it sends a welcome chat message if it is set" do - welcome_user = insert(:user) - clear_config([:welcome, :chat_message, :enabled], true) - clear_config([:welcome, :chat_message, :sender_nickname], welcome_user.nickname) - clear_config([:welcome, :chat_message, :message], "Hello, this is a chat message") - - cng = User.register_changeset(%User{}, @full_user_data) - {:ok, registered_user} = User.register(cng) - ObanHelpers.perform_all() - - activity = Repo.one(Pleroma.Activity) - assert registered_user.ap_id in activity.recipients - assert Object.normalize(activity, fetch: false).data["content"] =~ "chat message" - assert activity.actor == welcome_user.ap_id - end - setup do: clear_config(:mrf_simple, media_removal: [], @@ -480,24 +464,6 @@ defmodule Pleroma.UserTest do ] ) - test "it sends a welcome chat message when Simple policy applied to local instance" do - clear_config([:mrf_simple, :media_nsfw], [{"localhost", ""}]) - - welcome_user = insert(:user) - clear_config([:welcome, :chat_message, :enabled], true) - clear_config([:welcome, :chat_message, :sender_nickname], welcome_user.nickname) - clear_config([:welcome, :chat_message, :message], "Hello, this is a chat message") - - cng = User.register_changeset(%User{}, @full_user_data) - {:ok, registered_user} = User.register(cng) - ObanHelpers.perform_all() - - activity = Repo.one(Pleroma.Activity) - assert registered_user.ap_id in activity.recipients - assert Object.normalize(activity, fetch: false).data["content"] =~ "chat message" - assert activity.actor == welcome_user.ap_id - end - test "it sends a welcome email message if it is set" do welcome_user = insert(:user) clear_config([:welcome, :email, :enabled], true) @@ -665,15 +631,6 @@ defmodule Pleroma.UserTest do assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers" end - test "it sets the 'accepts_chat_messages' set to true" do - changeset = User.register_changeset(%User{}, @full_user_data) - assert changeset.valid? - - {:ok, user} = Repo.insert(changeset) - - assert user.accepts_chat_messages - end - test "it creates a confirmed user" do changeset = User.register_changeset(%User{}, @full_user_data) assert changeset.valid? diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 964437906..a5f971bbb 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -186,13 +186,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert User.invisible?(user) end - test "it returns a user that accepts chat messages" do - user_id = "http://mastodon.example.org/users/admin" - {:ok, user} = ActivityPub.make_user_from_ap_id(user_id) - - assert user.accepts_chat_messages - end - test "works for guppe actors" do user_id = "https://gup.pe/u/bernie2020" diff --git a/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs b/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs index 439672479..a88e1fa2e 100644 --- a/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs @@ -8,8 +8,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do import Pleroma.Web.ActivityPub.MRF.HellthreadPolicy - alias Pleroma.Web.CommonAPI - setup do user = insert(:user) @@ -33,17 +31,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do setup do: clear_config(:mrf_hellthread) - test "doesn't die on chat messages" do - clear_config([:mrf_hellthread], %{delist_threshold: 2, reject_threshold: 0}) - - user = insert(:user) - other_user = insert(:user) - - {:ok, activity} = CommonAPI.post_chat_message(user, other_user, "moin") - - assert {:ok, _} = filter(activity.data) - end - describe "reject" do test "rejects the message if the recipient count is above reject_threshold", %{ message: message diff --git a/test/pleroma/web/activity_pub/object_validators/chat_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/chat_validation_test.exs deleted file mode 100644 index def2a10b4..000000000 --- a/test/pleroma/web/activity_pub/object_validators/chat_validation_test.exs +++ /dev/null @@ -1,212 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do - use Pleroma.DataCase - alias Pleroma.Object - alias Pleroma.Web.ActivityPub.ActivityPub - alias Pleroma.Web.ActivityPub.Builder - alias Pleroma.Web.ActivityPub.ObjectValidator - alias Pleroma.Web.CommonAPI - - import Pleroma.Factory - - describe "chat message create activities" do - test "it is invalid if the object already exists" do - user = insert(:user) - recipient = insert(:user) - {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey") - object = Object.normalize(activity, fetch: false) - - {:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id]) - - {:error, cng} = ObjectValidator.validate(create_data, []) - - assert {:object, {"The object to create already exists", []}} in cng.errors - end - - test "it is invalid if the object data has a different `to` or `actor` field" do - user = insert(:user) - recipient = insert(:user) - {:ok, object_data, _} = Builder.chat_message(recipient, user.ap_id, "Hey") - - {:ok, create_data, _} = Builder.create(user, object_data, [recipient.ap_id]) - - {:error, cng} = ObjectValidator.validate(create_data, []) - - assert {:to, {"Recipients don't match with object recipients", []}} in cng.errors - assert {:actor, {"Actor doesn't match with object actor", []}} in cng.errors - end - end - - describe "chat messages" do - setup do - clear_config([:instance, :remote_limit]) - user = insert(:user) - recipient = insert(:user, local: false) - - {:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey :firefox:") - - %{user: user, recipient: recipient, valid_chat_message: valid_chat_message} - end - - test "let's through some basic html", %{user: user, recipient: recipient} do - {:ok, valid_chat_message, _} = - Builder.chat_message( - user, - recipient.ap_id, - "hey example " - ) - - assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, []) - - assert object["content"] == - "hey example alert('uguu')" - end - - test "validates for a basic object we build", %{valid_chat_message: valid_chat_message} do - assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, []) - - assert valid_chat_message == object - assert match?(%{"firefox" => _}, object["emoji"]) - end - - test "validates for a basic object with an attachment", %{ - valid_chat_message: valid_chat_message, - user: user - } do - file = %Plug.Upload{ - content_type: "image/jpeg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id) - - valid_chat_message = - valid_chat_message - |> Map.put("attachment", attachment.data) - - assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, []) - - assert object["attachment"] - end - - test "validates for a basic object with an attachment in an array", %{ - valid_chat_message: valid_chat_message, - user: user - } do - file = %Plug.Upload{ - content_type: "image/jpeg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id) - - valid_chat_message = - valid_chat_message - |> Map.put("attachment", [attachment.data]) - - assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, []) - - assert object["attachment"] - end - - test "validates for a basic object with an attachment but without content", %{ - valid_chat_message: valid_chat_message, - user: user - } do - file = %Plug.Upload{ - content_type: "image/jpeg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id) - - valid_chat_message = - valid_chat_message - |> Map.put("attachment", attachment.data) - |> Map.delete("content") - - assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, []) - - assert object["attachment"] - end - - test "does not validate if the message has no content", %{ - valid_chat_message: valid_chat_message - } do - contentless = - valid_chat_message - |> Map.delete("content") - - refute match?({:ok, _object, _meta}, ObjectValidator.validate(contentless, [])) - end - - test "does not validate if the message is longer than the remote_limit", %{ - valid_chat_message: valid_chat_message - } do - clear_config([:instance, :remote_limit], 2) - refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, [])) - end - - test "does not validate if the recipient is blocking the actor", %{ - valid_chat_message: valid_chat_message, - user: user, - recipient: recipient - } do - Pleroma.User.block(recipient, user) - refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, [])) - end - - test "does not validate if the recipient is not accepting chat messages", %{ - valid_chat_message: valid_chat_message, - recipient: recipient - } do - recipient - |> Ecto.Changeset.change(%{accepts_chat_messages: false}) - |> Pleroma.Repo.update!() - - refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, [])) - end - - test "does not validate if the actor or the recipient is not in our system", %{ - valid_chat_message: valid_chat_message - } do - chat_message = - valid_chat_message - |> Map.put("actor", "https://raymoo.com/raymoo") - - {:error, _} = ObjectValidator.validate(chat_message, []) - - chat_message = - valid_chat_message - |> Map.put("to", ["https://raymoo.com/raymoo"]) - - {:error, _} = ObjectValidator.validate(chat_message, []) - end - - test "does not validate for a message with multiple recipients", %{ - valid_chat_message: valid_chat_message, - user: user, - recipient: recipient - } do - chat_message = - valid_chat_message - |> Map.put("to", [user.ap_id, recipient.ap_id]) - - assert {:error, _} = ObjectValidator.validate(chat_message, []) - end - - test "does not validate if it doesn't concern local users" do - user = insert(:user, local: false) - recipient = insert(:user, local: false) - - {:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey") - assert {:error, _} = ObjectValidator.validate(valid_chat_message, []) - end - end -end diff --git a/test/pleroma/web/activity_pub/side_effects_test.exs b/test/pleroma/web/activity_pub/side_effects_test.exs index 82d43555f..e542c06f5 100644 --- a/test/pleroma/web/activity_pub/side_effects_test.exs +++ b/test/pleroma/web/activity_pub/side_effects_test.exs @@ -7,8 +7,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do use Pleroma.DataCase alias Pleroma.Activity - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo @@ -17,6 +15,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Builder alias Pleroma.Web.ActivityPub.SideEffects + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.CommonAPI import Mock @@ -27,15 +26,22 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do author = insert(:user, local: true) recipient = insert(:user, local: true) - {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey") + {:ok, note_data, _meta} = + Builder.note(%Pleroma.Web.CommonAPI.ActivityDraft{ + user: author, + to: [recipient.ap_id], + mentions: [recipient], + content_html: "hey", + extra: %{"id" => Utils.generate_object_id()} + }) {:ok, create_activity_data, _meta} = - Builder.create(author, chat_message_data["id"], [recipient.ap_id]) + Builder.create(author, note_data["id"], [recipient.ap_id]) {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false) {:ok, _create_activity, meta} = - SideEffects.handle(create_activity, local: false, object_data: chat_message_data) + SideEffects.handle(create_activity, local: false, object_data: note_data) assert [notification] = meta[:notifications] @@ -58,7 +64,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do SideEffects.handle_after_transaction(meta) assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification)) - assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_)) assert called(Pleroma.Web.Push.send(notification)) end end @@ -336,147 +341,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do end end - describe "creation of ChatMessages" do - test "notifies the recipient" do - author = insert(:user, local: false) - recipient = insert(:user, local: true) - - {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey") - - {:ok, create_activity_data, _meta} = - Builder.create(author, chat_message_data["id"], [recipient.ap_id]) - - {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false) - - {:ok, _create_activity, _meta} = - SideEffects.handle(create_activity, local: false, object_data: chat_message_data) - - assert Repo.get_by(Notification, user_id: recipient.id, activity_id: create_activity.id) - end - - test "it streams the created ChatMessage" do - author = insert(:user, local: true) - recipient = insert(:user, local: true) - - {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey") - - {:ok, create_activity_data, _meta} = - Builder.create(author, chat_message_data["id"], [recipient.ap_id]) - - {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false) - - {:ok, _create_activity, meta} = - SideEffects.handle(create_activity, local: false, object_data: chat_message_data) - - assert [_, _] = meta[:streamables] - end - - test "it creates a Chat and MessageReferences for the local users and bumps the unread count, except for the author" do - author = insert(:user, local: true) - recipient = insert(:user, local: true) - - {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey") - - {:ok, create_activity_data, _meta} = - Builder.create(author, chat_message_data["id"], [recipient.ap_id]) - - {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false) - - with_mocks([ - { - Pleroma.Web.Streamer, - [], - [ - stream: fn _, _ -> nil end - ] - }, - { - Pleroma.Web.Push, - [], - [ - send: fn _ -> nil end - ] - } - ]) do - {:ok, _create_activity, meta} = - SideEffects.handle(create_activity, local: false, object_data: chat_message_data) - - # The notification gets created - assert [notification] = meta[:notifications] - assert notification.activity_id == create_activity.id - - # But it is not sent out - refute called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification)) - refute called(Pleroma.Web.Push.send(notification)) - - # Same for the user chat stream - assert [{topics, _}, _] = meta[:streamables] - assert topics == ["user", "user:pleroma_chat"] - refute called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_)) - - chat = Chat.get(author.id, recipient.ap_id) - - [cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all() - - assert cm_ref.object.data["content"] == "hey" - assert cm_ref.unread == false - - chat = Chat.get(recipient.id, author.ap_id) - - [cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all() - - assert cm_ref.object.data["content"] == "hey" - assert cm_ref.unread == true - end - end - - test "it creates a Chat for the local users and bumps the unread count" do - author = insert(:user, local: false) - recipient = insert(:user, local: true) - - {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey") - - {:ok, create_activity_data, _meta} = - Builder.create(author, chat_message_data["id"], [recipient.ap_id]) - - {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false) - - {:ok, _create_activity, _meta} = - SideEffects.handle(create_activity, local: false, object_data: chat_message_data) - - # An object is created - assert Object.get_by_ap_id(chat_message_data["id"]) - - # The remote user won't get a chat - chat = Chat.get(author.id, recipient.ap_id) - refute chat - - # The local user will get a chat - chat = Chat.get(recipient.id, author.ap_id) - assert chat - - author = insert(:user, local: true) - recipient = insert(:user, local: true) - - {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey") - - {:ok, create_activity_data, _meta} = - Builder.create(author, chat_message_data["id"], [recipient.ap_id]) - - {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false) - - {:ok, _create_activity, _meta} = - SideEffects.handle(create_activity, local: false, object_data: chat_message_data) - - # Both users are local and get the chat - chat = Chat.get(author.id, recipient.ap_id) - assert chat - - chat = Chat.get(recipient.id, author.ap_id) - assert chat - end - end - describe "announce objects" do setup do poster = insert(:user) diff --git a/test/pleroma/web/activity_pub/transmogrifier/chat_message_test.exs b/test/pleroma/web/activity_pub/transmogrifier/chat_message_test.exs deleted file mode 100644 index 958675835..000000000 --- a/test/pleroma/web/activity_pub/transmogrifier/chat_message_test.exs +++ /dev/null @@ -1,171 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ActivityPub.Transmogrifier.ChatMessageTest do - use Pleroma.DataCase - - import Pleroma.Factory - - alias Pleroma.Activity - alias Pleroma.Chat - alias Pleroma.Object - alias Pleroma.Web.ActivityPub.Transmogrifier - - describe "handle_incoming" do - test "handles chonks with attachment" do - data = %{ - "@context" => "https://www.w3.org/ns/activitystreams", - "actor" => "https://honk.tedunangst.com/u/tedu", - "id" => "https://honk.tedunangst.com/u/tedu/honk/x6gt8X8PcyGkQcXxzg1T", - "object" => %{ - "attachment" => [ - %{ - "mediaType" => "image/jpeg", - "name" => "298p3RG7j27tfsZ9RQ.jpg", - "summary" => "298p3RG7j27tfsZ9RQ.jpg", - "type" => "Document", - "url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg" - } - ], - "attributedTo" => "https://honk.tedunangst.com/u/tedu", - "content" => "", - "id" => "https://honk.tedunangst.com/u/tedu/chonk/26L4wl5yCbn4dr4y1b", - "published" => "2020-05-18T01:13:03Z", - "to" => [ - "https://dontbulling.me/users/lain" - ], - "type" => "ChatMessage" - }, - "published" => "2020-05-18T01:13:03Z", - "to" => [ - "https://dontbulling.me/users/lain" - ], - "type" => "Create" - } - - _user = insert(:user, ap_id: data["actor"]) - _user = insert(:user, ap_id: hd(data["to"])) - - assert {:ok, _activity} = Transmogrifier.handle_incoming(data) - end - - test "it rejects messages that don't contain content" do - data = - File.read!("test/fixtures/create-chat-message.json") - |> Jason.decode!() - - object = - data["object"] - |> Map.delete("content") - - data = - data - |> Map.put("object", object) - - _author = - insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now()) - - _recipient = - insert(:user, - ap_id: List.first(data["to"]), - local: true, - last_refreshed_at: DateTime.utc_now() - ) - - {:error, _} = Transmogrifier.handle_incoming(data) - end - - test "it rejects messages that don't concern local users" do - data = - File.read!("test/fixtures/create-chat-message.json") - |> Jason.decode!() - - _author = - insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now()) - - _recipient = - insert(:user, - ap_id: List.first(data["to"]), - local: false, - last_refreshed_at: DateTime.utc_now() - ) - - {:error, _} = Transmogrifier.handle_incoming(data) - end - - test "it rejects messages where the `to` field of activity and object don't match" do - data = - File.read!("test/fixtures/create-chat-message.json") - |> Jason.decode!() - - author = insert(:user, ap_id: data["actor"]) - _recipient = insert(:user, ap_id: List.first(data["to"])) - - data = - data - |> Map.put("to", author.ap_id) - - assert match?({:error, _}, Transmogrifier.handle_incoming(data)) - refute Object.get_by_ap_id(data["object"]["id"]) - end - - test "it fetches the actor if they aren't in our system" do - Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end) - - data = - File.read!("test/fixtures/create-chat-message.json") - |> Jason.decode!() - |> Map.put("actor", "http://mastodon.example.org/users/admin") - |> put_in(["object", "actor"], "http://mastodon.example.org/users/admin") - - _recipient = insert(:user, ap_id: List.first(data["to"]), local: true) - - {:ok, %Activity{} = _activity} = Transmogrifier.handle_incoming(data) - end - - test "it doesn't work for deactivated users" do - data = - File.read!("test/fixtures/create-chat-message.json") - |> Jason.decode!() - - _author = - insert(:user, - ap_id: data["actor"], - local: false, - last_refreshed_at: DateTime.utc_now(), - is_active: false - ) - - _recipient = insert(:user, ap_id: List.first(data["to"]), local: true) - - assert {:error, _} = Transmogrifier.handle_incoming(data) - end - - test "it inserts it and creates a chat" do - data = - File.read!("test/fixtures/create-chat-message.json") - |> Jason.decode!() - - author = - insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now()) - - recipient = insert(:user, ap_id: List.first(data["to"]), local: true) - - {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data) - assert activity.local == false - - assert activity.actor == author.ap_id - assert activity.recipients == [recipient.ap_id, author.ap_id] - - %Object{} = object = Object.get_by_ap_id(activity.data["object"]) - - assert object - assert object.data["content"] == "You expected a cute girl? Too bad. alert('XSS')" - assert match?(%{"firefox" => _}, object.data["emoji"]) - - refute Chat.get(author.id, recipient.ap_id) - assert Chat.get(recipient.id, author.ap_id) - end - end -end diff --git a/test/pleroma/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs index f2de4d332..e49cb99d3 100644 --- a/test/pleroma/web/activity_pub/views/user_view_test.exs +++ b/test/pleroma/web/activity_pub/views/user_view_test.exs @@ -164,23 +164,4 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user}) end end - - describe "acceptsChatMessages" do - test "it returns this value if it is set" do - true_user = insert(:user, accepts_chat_messages: true) - false_user = insert(:user, accepts_chat_messages: false) - nil_user = insert(:user, accepts_chat_messages: nil) - - assert %{"capabilities" => %{"acceptsChatMessages" => true}} = - UserView.render("user.json", user: true_user) - - assert %{"capabilities" => %{"acceptsChatMessages" => false}} = - UserView.render("user.json", user: false_user) - - refute Map.has_key?( - UserView.render("user.json", user: nil_user)["capabilities"], - "acceptsChatMessages" - ) - end - end end diff --git a/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs index f8cd103c6..d74e0281c 100644 --- a/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs @@ -419,56 +419,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end end - describe "GET /api/pleroma/admin/users/:nickname/chats" do - setup do - user = insert(:user) - recipients = insert_list(3, :user) - - Enum.each(recipients, fn recipient -> - CommonAPI.post_chat_message(user, recipient, "yo") - end) - - %{user: user} - end - - test "renders user's chats", %{conn: conn, user: user} do - conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/chats") - - assert json_response(conn, 200) |> length() == 3 - end - end - - describe "GET /api/pleroma/admin/users/:nickname/chats unauthorized" do - setup do - user = insert(:user) - recipient = insert(:user) - CommonAPI.post_chat_message(user, recipient, "yo") - %{conn: conn} = oauth_access(["read:chats"]) - %{conn: conn, user: user} - end - - test "returns 403", %{conn: conn, user: user} do - conn - |> get("/api/pleroma/admin/users/#{user.nickname}/chats") - |> json_response(403) - end - end - - describe "GET /api/pleroma/admin/users/:nickname/chats unauthenticated" do - setup do - user = insert(:user) - recipient = insert(:user) - CommonAPI.post_chat_message(user, recipient, "yo") - %{conn: build_conn(), user: user} - end - - test "returns 403", %{conn: conn, user: user} do - conn - |> get("/api/pleroma/admin/users/#{user.nickname}/chats") - |> json_response(403) - end - end - describe "GET /api/pleroma/admin/moderation_log" do setup do moderator = insert(:user, is_moderator: true) diff --git a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs b/test/pleroma/web/admin_api/controllers/chat_controller_test.exs deleted file mode 100644 index 0e8f7beef..000000000 --- a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs +++ /dev/null @@ -1,218 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.AdminAPI.ChatControllerTest do - use Pleroma.Web.ConnCase, async: true - - import Pleroma.Factory - - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.ModerationLog - alias Pleroma.Object - alias Pleroma.Repo - alias Pleroma.Web.CommonAPI - - defp admin_setup do - admin = insert(:user, is_admin: true) - token = insert(:oauth_admin_token, user: admin) - - conn = - build_conn() - |> assign(:user, admin) - |> assign(:token, token) - - {:ok, %{admin: admin, token: token, conn: conn}} - end - - describe "DELETE /api/pleroma/admin/chats/:id/messages/:message_id" do - setup do: admin_setup() - - test "it deletes a message from the chat", %{conn: conn, admin: admin} do - user = insert(:user) - recipient = insert(:user) - - {:ok, message} = - CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend") - - object = Object.normalize(message, fetch: false) - - chat = Chat.get(user.id, recipient.ap_id) - recipient_chat = Chat.get(recipient.id, user.ap_id) - - cm_ref = MessageReference.for_chat_and_object(chat, object) - recipient_cm_ref = MessageReference.for_chat_and_object(recipient_chat, object) - - result = - conn - |> put_req_header("content-type", "application/json") - |> delete("/api/pleroma/admin/chats/#{chat.id}/messages/#{cm_ref.id}") - |> json_response_and_validate_schema(200) - - log_entry = Repo.one(ModerationLog) - - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} deleted chat message ##{cm_ref.id}" - - assert result["id"] == cm_ref.id - refute MessageReference.get_by_id(cm_ref.id) - refute MessageReference.get_by_id(recipient_cm_ref.id) - assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id) - end - end - - describe "GET /api/pleroma/admin/chats/:id/messages" do - setup do: admin_setup() - - test "it paginates", %{conn: conn} do - user = insert(:user) - recipient = insert(:user) - - Enum.each(1..30, fn _ -> - {:ok, _} = CommonAPI.post_chat_message(user, recipient, "hey") - end) - - chat = Chat.get(user.id, recipient.ap_id) - - result = - conn - |> get("/api/pleroma/admin/chats/#{chat.id}/messages") - |> json_response_and_validate_schema(200) - - assert length(result) == 20 - - result = - conn - |> get("/api/pleroma/admin/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}") - |> json_response_and_validate_schema(200) - - assert length(result) == 10 - end - - test "it returns the messages for a given chat", %{conn: conn} do - user = insert(:user) - other_user = insert(:user) - third_user = insert(:user) - - {:ok, _} = CommonAPI.post_chat_message(user, other_user, "hey") - {:ok, _} = CommonAPI.post_chat_message(user, third_user, "hey") - {:ok, _} = CommonAPI.post_chat_message(user, other_user, "how are you?") - {:ok, _} = CommonAPI.post_chat_message(other_user, user, "fine, how about you?") - - chat = Chat.get(user.id, other_user.ap_id) - - result = - conn - |> get("/api/pleroma/admin/chats/#{chat.id}/messages") - |> json_response_and_validate_schema(200) - - result - |> Enum.each(fn message -> - assert message["chat_id"] == chat.id |> to_string() - end) - - assert length(result) == 3 - end - end - - describe "GET /api/pleroma/admin/chats/:id" do - setup do: admin_setup() - - test "it returns a chat", %{conn: conn} do - user = insert(:user) - other_user = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - - result = - conn - |> get("/api/pleroma/admin/chats/#{chat.id}") - |> json_response_and_validate_schema(200) - - assert result["id"] == to_string(chat.id) - assert %{} = result["sender"] - assert %{} = result["receiver"] - refute result["account"] - end - end - - describe "unauthorized chat moderation" do - setup do - user = insert(:user) - recipient = insert(:user) - - {:ok, message} = CommonAPI.post_chat_message(user, recipient, "Yo") - object = Object.normalize(message, fetch: false) - chat = Chat.get(user.id, recipient.ap_id) - cm_ref = MessageReference.for_chat_and_object(chat, object) - - %{conn: conn} = oauth_access(["read:chats", "write:chats"]) - %{conn: conn, chat: chat, cm_ref: cm_ref} - end - - test "DELETE /api/pleroma/admin/chats/:id/messages/:message_id", %{ - conn: conn, - chat: chat, - cm_ref: cm_ref - } do - conn - |> put_req_header("content-type", "application/json") - |> delete("/api/pleroma/admin/chats/#{chat.id}/messages/#{cm_ref.id}") - |> json_response(403) - - assert MessageReference.get_by_id(cm_ref.id) == cm_ref - end - - test "GET /api/pleroma/admin/chats/:id/messages", %{conn: conn, chat: chat} do - conn - |> get("/api/pleroma/admin/chats/#{chat.id}/messages") - |> json_response(403) - end - - test "GET /api/pleroma/admin/chats/:id", %{conn: conn, chat: chat} do - conn - |> get("/api/pleroma/admin/chats/#{chat.id}") - |> json_response(403) - end - end - - describe "unauthenticated chat moderation" do - setup do - user = insert(:user) - recipient = insert(:user) - - {:ok, message} = CommonAPI.post_chat_message(user, recipient, "Yo") - object = Object.normalize(message, fetch: false) - chat = Chat.get(user.id, recipient.ap_id) - cm_ref = MessageReference.for_chat_and_object(chat, object) - - %{conn: build_conn(), chat: chat, cm_ref: cm_ref} - end - - test "DELETE /api/pleroma/admin/chats/:id/messages/:message_id", %{ - conn: conn, - chat: chat, - cm_ref: cm_ref - } do - conn - |> put_req_header("content-type", "application/json") - |> delete("/api/pleroma/admin/chats/#{chat.id}/messages/#{cm_ref.id}") - |> json_response(403) - - assert MessageReference.get_by_id(cm_ref.id) == cm_ref - end - - test "GET /api/pleroma/admin/chats/:id/messages", %{conn: conn, chat: chat} do - conn - |> get("/api/pleroma/admin/chats/#{chat.id}/messages") - |> json_response(403) - end - - test "GET /api/pleroma/admin/chats/:id", %{conn: conn, chat: chat} do - conn - |> get("/api/pleroma/admin/chats/#{chat.id}") - |> json_response(403) - end - end -end diff --git a/test/pleroma/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs deleted file mode 100644 index 9c9e8513c..000000000 --- a/test/pleroma/web/admin_api/controllers/config_controller_test.exs +++ /dev/null @@ -1,1525 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do - use Pleroma.Web.ConnCase - - import ExUnit.CaptureLog - import Pleroma.Factory - - alias Pleroma.ConfigDB - - setup do - admin = insert(:user, is_admin: true) - token = insert(:oauth_admin_token, user: admin) - - conn = - build_conn() - |> assign(:user, admin) - |> assign(:token, token) - - {:ok, %{admin: admin, token: token, conn: conn}} - end - - describe "GET /api/pleroma/admin/config" do - setup do: clear_config(:configurable_from_database, true) - - test "when configuration from database is off", %{conn: conn} do - clear_config(:configurable_from_database, false) - conn = get(conn, "/api/pleroma/admin/config") - - assert json_response_and_validate_schema(conn, 400) == - %{ - "error" => "You must enable configurable_from_database in your config file." - } - end - - test "with settings only in db", %{conn: conn} do - config1 = insert(:config) - config2 = insert(:config) - - conn = get(conn, "/api/pleroma/admin/config?only_db=true") - - %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => key1, - "value" => _ - }, - %{ - "group" => ":pleroma", - "key" => key2, - "value" => _ - } - ] - } = json_response_and_validate_schema(conn, 200) - - assert key1 == inspect(config1.key) - assert key2 == inspect(config2.key) - end - - test "db is added to settings that are in db", %{conn: conn} do - _config = insert(:config, key: ":instance", value: [name: "Some name"]) - - %{"configs" => configs} = - conn - |> get("/api/pleroma/admin/config") - |> json_response_and_validate_schema(200) - - [instance_config] = - Enum.filter(configs, fn %{"group" => group, "key" => key} -> - group == ":pleroma" and key == ":instance" - end) - - assert instance_config["db"] == [":name"] - end - - test "merged default setting with db settings", %{conn: conn} do - config1 = insert(:config) - config2 = insert(:config) - - config3 = - insert(:config, - value: [k1: :v1, k2: :v2] - ) - - %{"configs" => configs} = - conn - |> get("/api/pleroma/admin/config") - |> json_response_and_validate_schema(200) - - assert length(configs) > 3 - - saved_configs = [config1, config2, config3] - keys = Enum.map(saved_configs, &inspect(&1.key)) - - received_configs = - Enum.filter(configs, fn %{"group" => group, "key" => key} -> - group == ":pleroma" and key in keys - end) - - assert length(received_configs) == 3 - - db_keys = - config3.value - |> Keyword.keys() - |> ConfigDB.to_json_types() - - keys = Enum.map(saved_configs -- [config3], &inspect(&1.key)) - - values = Enum.map(saved_configs, &ConfigDB.to_json_types(&1.value)) - - mapset_keys = MapSet.new(keys ++ db_keys) - - Enum.each(received_configs, fn %{"value" => value, "db" => db} -> - db = MapSet.new(db) - assert MapSet.subset?(db, mapset_keys) - - assert value in values - end) - end - - test "subkeys with full update right merge", %{conn: conn} do - insert(:config, - key: ":emoji", - value: [groups: [a: 1, b: 2], key: [a: 1]] - ) - - insert(:config, - key: ":assets", - value: [mascots: [a: 1, b: 2], key: [a: 1]] - ) - - %{"configs" => configs} = - conn - |> get("/api/pleroma/admin/config") - |> json_response_and_validate_schema(200) - - vals = - Enum.filter(configs, fn %{"group" => group, "key" => key} -> - group == ":pleroma" and key in [":emoji", ":assets"] - end) - - emoji = Enum.find(vals, fn %{"key" => key} -> key == ":emoji" end) - assets = Enum.find(vals, fn %{"key" => key} -> key == ":assets" end) - - emoji_val = ConfigDB.to_elixir_types(emoji["value"]) - assets_val = ConfigDB.to_elixir_types(assets["value"]) - - assert emoji_val[:groups] == [a: 1, b: 2] - assert assets_val[:mascots] == [a: 1, b: 2] - end - - test "with valid `admin_token` query parameter, skips OAuth scopes check" do - clear_config([:admin_token], "password123") - - build_conn() - |> get("/api/pleroma/admin/config?admin_token=password123") - |> json_response_and_validate_schema(200) - end - end - - test "POST /api/pleroma/admin/config with configdb disabled", %{conn: conn} do - clear_config(:configurable_from_database, false) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{"configs" => []}) - - assert json_response_and_validate_schema(conn, 400) == - %{"error" => "You must enable configurable_from_database in your config file."} - end - - describe "POST /api/pleroma/admin/config" do - setup do - http = Application.get_env(:pleroma, :http) - - on_exit(fn -> - Application.delete_env(:pleroma, :key1) - Application.delete_env(:pleroma, :key2) - Application.delete_env(:pleroma, :key3) - Application.delete_env(:pleroma, :key4) - Application.delete_env(:pleroma, :keyaa1) - Application.delete_env(:pleroma, :keyaa2) - Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal) - Application.delete_env(:pleroma, Pleroma.Captcha.NotReal) - Application.put_env(:pleroma, :http, http) - Application.put_env(:tesla, :adapter, Tesla.Mock) - Restarter.Pleroma.refresh() - end) - end - - setup do: clear_config(:configurable_from_database, true) - - @tag capture_log: true - test "create new config setting in db", %{conn: conn} do - ueberauth = Application.get_env(:ueberauth, Ueberauth) - on_exit(fn -> Application.put_env(:ueberauth, Ueberauth, ueberauth) end) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{group: ":pleroma", key: ":key1", value: "value1"}, - %{ - group: ":ueberauth", - key: "Ueberauth", - value: [%{"tuple" => [":consumer_secret", "aaaa"]}] - }, - %{ - group: ":pleroma", - key: ":key2", - value: %{ - ":nested_1" => "nested_value1", - ":nested_2" => [ - %{":nested_22" => "nested_value222"}, - %{":nested_33" => %{":nested_44" => "nested_444"}} - ] - } - }, - %{ - group: ":pleroma", - key: ":key3", - value: [ - %{"nested_3" => ":nested_3", "nested_33" => "nested_33"}, - %{"nested_4" => true} - ] - }, - %{ - group: ":pleroma", - key: ":key4", - value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"} - }, - %{ - group: ":idna", - key: ":key5", - value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]} - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => "value1", - "db" => [":key1"] - }, - %{ - "group" => ":ueberauth", - "key" => "Ueberauth", - "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}], - "db" => [":consumer_secret"] - }, - %{ - "group" => ":pleroma", - "key" => ":key2", - "value" => %{ - ":nested_1" => "nested_value1", - ":nested_2" => [ - %{":nested_22" => "nested_value222"}, - %{":nested_33" => %{":nested_44" => "nested_444"}} - ] - }, - "db" => [":key2"] - }, - %{ - "group" => ":pleroma", - "key" => ":key3", - "value" => [ - %{"nested_3" => ":nested_3", "nested_33" => "nested_33"}, - %{"nested_4" => true} - ], - "db" => [":key3"] - }, - %{ - "group" => ":pleroma", - "key" => ":key4", - "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}, - "db" => [":key4"] - }, - %{ - "group" => ":idna", - "key" => ":key5", - "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}, - "db" => [":key5"] - } - ], - "need_reboot" => false - } - - assert Application.get_env(:pleroma, :key1) == "value1" - - assert Application.get_env(:pleroma, :key2) == %{ - nested_1: "nested_value1", - nested_2: [ - %{nested_22: "nested_value222"}, - %{nested_33: %{nested_44: "nested_444"}} - ] - } - - assert Application.get_env(:pleroma, :key3) == [ - %{"nested_3" => :nested_3, "nested_33" => "nested_33"}, - %{"nested_4" => true} - ] - - assert Application.get_env(:pleroma, :key4) == %{ - "endpoint" => "https://example.com", - nested_5: :upload - } - - assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []} - end - - test "save configs setting without explicit key", %{conn: conn} do - level = Application.get_env(:quack, :level) - meta = Application.get_env(:quack, :meta) - webhook_url = Application.get_env(:quack, :webhook_url) - - on_exit(fn -> - Application.put_env(:quack, :level, level) - Application.put_env(:quack, :meta, meta) - Application.put_env(:quack, :webhook_url, webhook_url) - end) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":quack", - key: ":level", - value: ":info" - }, - %{ - group: ":quack", - key: ":meta", - value: [":none"] - }, - %{ - group: ":quack", - key: ":webhook_url", - value: "https://hooks.slack.com/services/KEY" - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":quack", - "key" => ":level", - "value" => ":info", - "db" => [":level"] - }, - %{ - "group" => ":quack", - "key" => ":meta", - "value" => [":none"], - "db" => [":meta"] - }, - %{ - "group" => ":quack", - "key" => ":webhook_url", - "value" => "https://hooks.slack.com/services/KEY", - "db" => [":webhook_url"] - } - ], - "need_reboot" => false - } - - assert Application.get_env(:quack, :level) == :info - assert Application.get_env(:quack, :meta) == [:none] - assert Application.get_env(:quack, :webhook_url) == "https://hooks.slack.com/services/KEY" - end - - test "saving config with partial update", %{conn: conn} do - insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: 2)) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{group: ":pleroma", key: ":key1", value: [%{"tuple" => [":key3", 3]}]} - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => [ - %{"tuple" => [":key1", 1]}, - %{"tuple" => [":key2", 2]}, - %{"tuple" => [":key3", 3]} - ], - "db" => [":key1", ":key2", ":key3"] - } - ], - "need_reboot" => false - } - end - - test "saving config which need pleroma reboot", %{conn: conn} do - clear_config([:shout, :enabled], true) - - assert conn - |> put_req_header("content-type", "application/json") - |> post( - "/api/pleroma/admin/config", - %{ - configs: [ - %{group: ":pleroma", key: ":shout", value: [%{"tuple" => [":enabled", true]}]} - ] - } - ) - |> json_response_and_validate_schema(200) == %{ - "configs" => [ - %{ - "db" => [":enabled"], - "group" => ":pleroma", - "key" => ":shout", - "value" => [%{"tuple" => [":enabled", true]}] - } - ], - "need_reboot" => true - } - - configs = - conn - |> get("/api/pleroma/admin/config") - |> json_response_and_validate_schema(200) - - assert configs["need_reboot"] - - capture_log(fn -> - assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == - %{} - end) =~ "pleroma restarted" - - configs = - conn - |> get("/api/pleroma/admin/config") - |> json_response_and_validate_schema(200) - - assert configs["need_reboot"] == false - end - - test "update setting which need reboot, don't change reboot flag until reboot", %{conn: conn} do - clear_config([:shout, :enabled], true) - - assert conn - |> put_req_header("content-type", "application/json") - |> post( - "/api/pleroma/admin/config", - %{ - configs: [ - %{group: ":pleroma", key: ":shout", value: [%{"tuple" => [":enabled", true]}]} - ] - } - ) - |> json_response_and_validate_schema(200) == %{ - "configs" => [ - %{ - "db" => [":enabled"], - "group" => ":pleroma", - "key" => ":shout", - "value" => [%{"tuple" => [":enabled", true]}] - } - ], - "need_reboot" => true - } - - assert conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{group: ":pleroma", key: ":key1", value: [%{"tuple" => [":key3", 3]}]} - ] - }) - |> json_response_and_validate_schema(200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => [ - %{"tuple" => [":key3", 3]} - ], - "db" => [":key3"] - } - ], - "need_reboot" => true - } - - capture_log(fn -> - assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == - %{} - end) =~ "pleroma restarted" - - configs = - conn - |> get("/api/pleroma/admin/config") - |> json_response_and_validate_schema(200) - - assert configs["need_reboot"] == false - end - - test "saving config with nested merge", %{conn: conn} do - insert(:config, key: :key1, value: [key1: 1, key2: [k1: 1, k2: 2]]) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":pleroma", - key: ":key1", - value: [ - %{"tuple" => [":key3", 3]}, - %{ - "tuple" => [ - ":key2", - [ - %{"tuple" => [":k2", 1]}, - %{"tuple" => [":k3", 3]} - ] - ] - } - ] - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => [ - %{"tuple" => [":key1", 1]}, - %{"tuple" => [":key3", 3]}, - %{ - "tuple" => [ - ":key2", - [ - %{"tuple" => [":k1", 1]}, - %{"tuple" => [":k2", 1]}, - %{"tuple" => [":k3", 3]} - ] - ] - } - ], - "db" => [":key1", ":key3", ":key2"] - } - ], - "need_reboot" => false - } - end - - test "saving special atoms", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => [ - %{ - "tuple" => [ - ":ssl_options", - [%{"tuple" => [":versions", [":tlsv1", ":tlsv1.1", ":tlsv1.2"]]}] - ] - } - ] - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => [ - %{ - "tuple" => [ - ":ssl_options", - [%{"tuple" => [":versions", [":tlsv1", ":tlsv1.1", ":tlsv1.2"]]}] - ] - } - ], - "db" => [":ssl_options"] - } - ], - "need_reboot" => false - } - - assert Application.get_env(:pleroma, :key1) == [ - ssl_options: [versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"]] - ] - end - - test "saving full setting if value is in full_key_update list", %{conn: conn} do - backends = Application.get_env(:logger, :backends) - on_exit(fn -> Application.put_env(:logger, :backends, backends) end) - - insert(:config, - group: :logger, - key: :backends, - value: [] - ) - - Pleroma.Config.TransferTask.load_and_update_env([], false) - - assert Application.get_env(:logger, :backends) == [] - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":logger", - key: ":backends", - value: [":console"] - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":logger", - "key" => ":backends", - "value" => [ - ":console" - ], - "db" => [":backends"] - } - ], - "need_reboot" => false - } - - assert Application.get_env(:logger, :backends) == [ - :console - ] - end - - test "saving full setting if value is not keyword", %{conn: conn} do - insert(:config, - group: :tesla, - key: :adapter, - value: Tesla.Adapter.Hackey - ) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{group: ":tesla", key: ":adapter", value: "Tesla.Adapter.Httpc"} - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":tesla", - "key" => ":adapter", - "value" => "Tesla.Adapter.Httpc", - "db" => [":adapter"] - } - ], - "need_reboot" => false - } - end - - test "update config setting & delete with fallback to default value", %{ - conn: conn, - admin: admin, - token: token - } do - ueberauth = Application.get_env(:ueberauth, Ueberauth) - insert(:config, key: :keyaa1) - insert(:config, key: :keyaa2) - - config3 = - insert(:config, - group: :ueberauth, - key: Ueberauth - ) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{group: ":pleroma", key: ":keyaa1", value: "another_value"}, - %{group: ":pleroma", key: ":keyaa2", value: "another_value"} - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":keyaa1", - "value" => "another_value", - "db" => [":keyaa1"] - }, - %{ - "group" => ":pleroma", - "key" => ":keyaa2", - "value" => "another_value", - "db" => [":keyaa2"] - } - ], - "need_reboot" => false - } - - assert Application.get_env(:pleroma, :keyaa1) == "another_value" - assert Application.get_env(:pleroma, :keyaa2) == "another_value" - assert Application.get_env(:ueberauth, Ueberauth) == config3.value - - conn = - build_conn() - |> assign(:user, admin) - |> assign(:token, token) - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{group: ":pleroma", key: ":keyaa2", delete: true}, - %{ - group: ":ueberauth", - key: "Ueberauth", - delete: true - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [], - "need_reboot" => false - } - - assert Application.get_env(:ueberauth, Ueberauth) == ueberauth - refute Keyword.has_key?(Application.get_all_env(:pleroma), :keyaa2) - end - - test "common config example", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - "group" => ":pleroma", - "key" => "Pleroma.Captcha.NotReal", - "value" => [ - %{"tuple" => [":enabled", false]}, - %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]}, - %{"tuple" => [":seconds_valid", 60]}, - %{"tuple" => [":path", ""]}, - %{"tuple" => [":key1", nil]}, - %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}, - %{"tuple" => [":regex1", "~r/https:\/\/example.com/"]}, - %{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]}, - %{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]}, - %{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]}, - %{"tuple" => [":name", "Pleroma"]} - ] - } - ] - }) - - assert Config.get([Pleroma.Captcha.NotReal, :name]) == "Pleroma" - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => "Pleroma.Captcha.NotReal", - "value" => [ - %{"tuple" => [":enabled", false]}, - %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]}, - %{"tuple" => [":seconds_valid", 60]}, - %{"tuple" => [":path", ""]}, - %{"tuple" => [":key1", nil]}, - %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}, - %{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]}, - %{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]}, - %{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]}, - %{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]}, - %{"tuple" => [":name", "Pleroma"]} - ], - "db" => [ - ":enabled", - ":method", - ":seconds_valid", - ":path", - ":key1", - ":partial_chain", - ":regex1", - ":regex2", - ":regex3", - ":regex4", - ":name" - ] - } - ], - "need_reboot" => false - } - end - - test "tuples with more than two values", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - "group" => ":pleroma", - "key" => "Pleroma.Web.Endpoint.NotReal", - "value" => [ - %{ - "tuple" => [ - ":http", - [ - %{ - "tuple" => [ - ":key2", - [ - %{ - "tuple" => [ - ":_", - [ - %{ - "tuple" => [ - "/api/v1/streaming", - "Pleroma.Web.MastodonAPI.WebsocketHandler", - [] - ] - }, - %{ - "tuple" => [ - "/websocket", - "Phoenix.Endpoint.CowboyWebSocket", - %{ - "tuple" => [ - "Phoenix.Transports.WebSocket", - %{ - "tuple" => [ - "Pleroma.Web.Endpoint", - "Pleroma.Web.UserSocket", - [] - ] - } - ] - } - ] - }, - %{ - "tuple" => [ - ":_", - "Phoenix.Endpoint.Cowboy2Handler", - %{"tuple" => ["Pleroma.Web.Endpoint", []]} - ] - } - ] - ] - } - ] - ] - } - ] - ] - } - ] - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => "Pleroma.Web.Endpoint.NotReal", - "value" => [ - %{ - "tuple" => [ - ":http", - [ - %{ - "tuple" => [ - ":key2", - [ - %{ - "tuple" => [ - ":_", - [ - %{ - "tuple" => [ - "/api/v1/streaming", - "Pleroma.Web.MastodonAPI.WebsocketHandler", - [] - ] - }, - %{ - "tuple" => [ - "/websocket", - "Phoenix.Endpoint.CowboyWebSocket", - %{ - "tuple" => [ - "Phoenix.Transports.WebSocket", - %{ - "tuple" => [ - "Pleroma.Web.Endpoint", - "Pleroma.Web.UserSocket", - [] - ] - } - ] - } - ] - }, - %{ - "tuple" => [ - ":_", - "Phoenix.Endpoint.Cowboy2Handler", - %{"tuple" => ["Pleroma.Web.Endpoint", []]} - ] - } - ] - ] - } - ] - ] - } - ] - ] - } - ], - "db" => [":http"] - } - ], - "need_reboot" => false - } - end - - test "settings with nesting map", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => [ - %{"tuple" => [":key2", "some_val"]}, - %{ - "tuple" => [ - ":key3", - %{ - ":max_options" => 20, - ":max_option_chars" => 200, - ":min_expiration" => 0, - ":max_expiration" => 31_536_000, - "nested" => %{ - ":max_options" => 20, - ":max_option_chars" => 200, - ":min_expiration" => 0, - ":max_expiration" => 31_536_000 - } - } - ] - } - ] - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == - %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => [ - %{"tuple" => [":key2", "some_val"]}, - %{ - "tuple" => [ - ":key3", - %{ - ":max_expiration" => 31_536_000, - ":max_option_chars" => 200, - ":max_options" => 20, - ":min_expiration" => 0, - "nested" => %{ - ":max_expiration" => 31_536_000, - ":max_option_chars" => 200, - ":max_options" => 20, - ":min_expiration" => 0 - } - } - ] - } - ], - "db" => [":key2", ":key3"] - } - ], - "need_reboot" => false - } - end - - test "value as map", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => %{"key" => "some_val"} - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == - %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":key1", - "value" => %{"key" => "some_val"}, - "db" => [":key1"] - } - ], - "need_reboot" => false - } - end - - test "queues key as atom", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - "group" => ":oban", - "key" => ":queues", - "value" => [ - %{"tuple" => [":federator_incoming", 50]}, - %{"tuple" => [":federator_outgoing", 50]}, - %{"tuple" => [":web_push", 50]}, - %{"tuple" => [":mailer", 10]}, - %{"tuple" => [":transmogrifier", 20]}, - %{"tuple" => [":scheduled_activities", 10]}, - %{"tuple" => [":background", 5]} - ] - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":oban", - "key" => ":queues", - "value" => [ - %{"tuple" => [":federator_incoming", 50]}, - %{"tuple" => [":federator_outgoing", 50]}, - %{"tuple" => [":web_push", 50]}, - %{"tuple" => [":mailer", 10]}, - %{"tuple" => [":transmogrifier", 20]}, - %{"tuple" => [":scheduled_activities", 10]}, - %{"tuple" => [":background", 5]} - ], - "db" => [ - ":federator_incoming", - ":federator_outgoing", - ":web_push", - ":mailer", - ":transmogrifier", - ":scheduled_activities", - ":background" - ] - } - ], - "need_reboot" => false - } - end - - test "delete part of settings by atom subkeys", %{conn: conn} do - insert(:config, - key: :keyaa1, - value: [subkey1: "val1", subkey2: "val2", subkey3: "val3"] - ) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":pleroma", - key: ":keyaa1", - subkeys: [":subkey1", ":subkey3"], - delete: true - } - ] - }) - - assert json_response_and_validate_schema(conn, 200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":keyaa1", - "value" => [%{"tuple" => [":subkey2", "val2"]}], - "db" => [":subkey2"] - } - ], - "need_reboot" => false - } - end - - test "proxy tuple localhost", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":pleroma", - key: ":http", - value: [ - %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]} - ] - } - ] - }) - - assert %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":http", - "value" => value, - "db" => db - } - ] - } = json_response_and_validate_schema(conn, 200) - - assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]} in value - assert ":proxy_url" in db - end - - test "proxy tuple domain", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":pleroma", - key: ":http", - value: [ - %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]} - ] - } - ] - }) - - assert %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":http", - "value" => value, - "db" => db - } - ] - } = json_response_and_validate_schema(conn, 200) - - assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]} in value - assert ":proxy_url" in db - end - - test "proxy tuple ip", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":pleroma", - key: ":http", - value: [ - %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]} - ] - } - ] - }) - - assert %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => ":http", - "value" => value, - "db" => db - } - ] - } = json_response_and_validate_schema(conn, 200) - - assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]} in value - assert ":proxy_url" in db - end - - @tag capture_log: true - test "doesn't set keys not in the whitelist", %{conn: conn} do - clear_config(:database_config_whitelist, [ - {:pleroma, :key1}, - {:pleroma, :key2}, - {:pleroma, Pleroma.Captcha.NotReal}, - {:not_real} - ]) - - conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{group: ":pleroma", key: ":key1", value: "value1"}, - %{group: ":pleroma", key: ":key2", value: "value2"}, - %{group: ":pleroma", key: ":key3", value: "value3"}, - %{group: ":pleroma", key: "Pleroma.Web.Endpoint.NotReal", value: "value4"}, - %{group: ":pleroma", key: "Pleroma.Captcha.NotReal", value: "value5"}, - %{group: ":not_real", key: ":anything", value: "value6"} - ] - }) - - assert Application.get_env(:pleroma, :key1) == "value1" - assert Application.get_env(:pleroma, :key2) == "value2" - assert Application.get_env(:pleroma, :key3) == nil - assert Application.get_env(:pleroma, Pleroma.Web.Endpoint.NotReal) == nil - assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == "value5" - assert Application.get_env(:not_real, :anything) == "value6" - end - - test "args for Pleroma.Upload.Filter.Mogrify with custom tuples", %{conn: conn} do - clear_config(Pleroma.Upload.Filter.Mogrify) - - assert conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":pleroma", - key: "Pleroma.Upload.Filter.Mogrify", - value: [ - %{"tuple" => [":args", ["auto-orient", "strip"]]} - ] - } - ] - }) - |> json_response_and_validate_schema(200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => "Pleroma.Upload.Filter.Mogrify", - "value" => [ - %{"tuple" => [":args", ["auto-orient", "strip"]]} - ], - "db" => [":args"] - } - ], - "need_reboot" => false - } - - assert Config.get(Pleroma.Upload.Filter.Mogrify) == [args: ["auto-orient", "strip"]] - - assert conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{ - configs: [ - %{ - group: ":pleroma", - key: "Pleroma.Upload.Filter.Mogrify", - value: [ - %{ - "tuple" => [ - ":args", - [ - "auto-orient", - "strip", - "{\"implode\", \"1\"}", - "{\"resize\", \"3840x1080>\"}" - ] - ] - } - ] - } - ] - }) - |> json_response(200) == %{ - "configs" => [ - %{ - "group" => ":pleroma", - "key" => "Pleroma.Upload.Filter.Mogrify", - "value" => [ - %{ - "tuple" => [ - ":args", - [ - "auto-orient", - "strip", - "{\"implode\", \"1\"}", - "{\"resize\", \"3840x1080>\"}" - ] - ] - } - ], - "db" => [":args"] - } - ], - "need_reboot" => false - } - - assert Config.get(Pleroma.Upload.Filter.Mogrify) == [ - args: ["auto-orient", "strip", {"implode", "1"}, {"resize", "3840x1080>"}] - ] - end - - test "enables the welcome messages", %{conn: conn} do - clear_config([:welcome]) - - params = %{ - "group" => ":pleroma", - "key" => ":welcome", - "value" => [ - %{ - "tuple" => [ - ":direct_message", - [ - %{"tuple" => [":enabled", true]}, - %{"tuple" => [":message", "Welcome to Pleroma!"]}, - %{"tuple" => [":sender_nickname", "pleroma"]} - ] - ] - }, - %{ - "tuple" => [ - ":chat_message", - [ - %{"tuple" => [":enabled", true]}, - %{"tuple" => [":message", "Welcome to Pleroma!"]}, - %{"tuple" => [":sender_nickname", "pleroma"]} - ] - ] - }, - %{ - "tuple" => [ - ":email", - [ - %{"tuple" => [":enabled", true]}, - %{"tuple" => [":sender", %{"tuple" => ["pleroma@dev.dev", "Pleroma"]}]}, - %{"tuple" => [":subject", "Welcome to <%= instance_name %>!"]}, - %{"tuple" => [":html", "Welcome to <%= instance_name %>!"]}, - %{"tuple" => [":text", "Welcome to <%= instance_name %>!"]} - ] - ] - } - ] - } - - refute Pleroma.User.WelcomeEmail.enabled?() - refute Pleroma.User.WelcomeMessage.enabled?() - refute Pleroma.User.WelcomeChatMessage.enabled?() - - res = - assert conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{"configs" => [params]}) - |> json_response_and_validate_schema(200) - - assert Pleroma.User.WelcomeEmail.enabled?() - assert Pleroma.User.WelcomeMessage.enabled?() - assert Pleroma.User.WelcomeChatMessage.enabled?() - - assert res == %{ - "configs" => [ - %{ - "db" => [":direct_message", ":chat_message", ":email"], - "group" => ":pleroma", - "key" => ":welcome", - "value" => params["value"] - } - ], - "need_reboot" => false - } - end - - test "custom instance thumbnail", %{conn: conn} do - clear_config([:instance]) - - params = %{ - "group" => ":pleroma", - "key" => ":instance", - "value" => [ - %{ - "tuple" => [ - ":instance_thumbnail", - "https://example.com/media/new_thumbnail.jpg" - ] - } - ] - } - - assert conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{"configs" => [params]}) - |> json_response_and_validate_schema(200) == - %{ - "configs" => [ - %{ - "db" => [":instance_thumbnail"], - "group" => ":pleroma", - "key" => ":instance", - "value" => params["value"] - } - ], - "need_reboot" => false - } - - assert conn - |> get("/api/v1/instance") - |> json_response_and_validate_schema(200) - |> Map.take(["thumbnail"]) == - %{"thumbnail" => "https://example.com/media/new_thumbnail.jpg"} - end - - test "Concurrent Limiter", %{conn: conn} do - clear_config([ConcurrentLimiter]) - - params = %{ - "group" => ":pleroma", - "key" => "ConcurrentLimiter", - "value" => [ - %{ - "tuple" => [ - "Pleroma.Web.RichMedia.Helpers", - [ - %{"tuple" => [":max_running", 6]}, - %{"tuple" => [":max_waiting", 6]} - ] - ] - }, - %{ - "tuple" => [ - "Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy", - [ - %{"tuple" => [":max_running", 7]}, - %{"tuple" => [":max_waiting", 7]} - ] - ] - } - ] - } - - assert conn - |> put_req_header("content-type", "application/json") - |> post("/api/pleroma/admin/config", %{"configs" => [params]}) - |> json_response_and_validate_schema(200) - end - end - - describe "GET /api/pleroma/admin/config/descriptions" do - test "structure", %{conn: conn} do - conn = get(conn, "/api/pleroma/admin/config/descriptions") - - assert [child | _others] = json_response_and_validate_schema(conn, 200) - - assert child["children"] - assert child["key"] - assert String.starts_with?(child["group"], ":") - assert child["description"] - end - - test "filters by database configuration whitelist", %{conn: conn} do - clear_config(:database_config_whitelist, [ - {:pleroma, :instance}, - {:pleroma, :activitypub}, - {:pleroma, Pleroma.Upload} - ]) - - conn = get(conn, "/api/pleroma/admin/config/descriptions") - - children = json_response_and_validate_schema(conn, 200) - - assert length(children) == 3 - - assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 3 - - instance = Enum.find(children, fn c -> c["key"] == ":instance" end) - assert instance["children"] - - activitypub = Enum.find(children, fn c -> c["key"] == ":activitypub" end) - assert activitypub["children"] - - web_endpoint = Enum.find(children, fn c -> c["key"] == "Pleroma.Upload" end) - assert web_endpoint["children"] - end - end -end diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs index 167909cfb..09b09fb14 100644 --- a/test/pleroma/web/common_api_test.exs +++ b/test/pleroma/web/common_api_test.exs @@ -7,13 +7,11 @@ defmodule Pleroma.Web.CommonAPITest do use Pleroma.DataCase alias Pleroma.Activity - alias Pleroma.Chat alias Pleroma.Conversation.Participation alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User - alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.AdminAPI.AccountView @@ -106,173 +104,6 @@ defmodule Pleroma.Web.CommonAPITest do end end - describe "posting chat messages" do - setup do: clear_config([:instance, :chat_limit]) - - test "it posts a self-chat" do - author = insert(:user) - recipient = author - - {:ok, activity} = - CommonAPI.post_chat_message( - author, - recipient, - "remember to buy milk when milk truk arive" - ) - - assert activity.data["type"] == "Create" - end - - test "it posts a chat message without content but with an attachment" do - author = insert(:user) - recipient = insert(:user) - - file = %Plug.Upload{ - content_type: "image/jpeg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, upload} = ActivityPub.upload(file, actor: author.ap_id) - - with_mocks([ - { - Pleroma.Web.Streamer, - [], - [ - stream: fn _, _ -> - nil - end - ] - }, - { - Pleroma.Web.Push, - [], - [ - send: fn _ -> nil end - ] - } - ]) do - {:ok, activity} = - CommonAPI.post_chat_message( - author, - recipient, - nil, - media_id: upload.id - ) - - notification = - Notification.for_user_and_activity(recipient, activity) - |> Repo.preload(:activity) - - assert called(Pleroma.Web.Push.send(notification)) - assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification)) - assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_)) - - assert activity - end - end - - test "it adds html newlines" do - author = insert(:user) - recipient = insert(:user) - - other_user = insert(:user) - - {:ok, activity} = - CommonAPI.post_chat_message( - author, - recipient, - "uguu\nuguuu" - ) - - assert other_user.ap_id not in activity.recipients - - object = Object.normalize(activity, fetch: false) - - assert object.data["content"] == "uguu
uguuu" - end - - test "it linkifies" do - author = insert(:user) - recipient = insert(:user) - - other_user = insert(:user) - - {:ok, activity} = - CommonAPI.post_chat_message( - author, - recipient, - "https://example.org is the site of @#{other_user.nickname} #2hu" - ) - - assert other_user.ap_id not in activity.recipients - - object = Object.normalize(activity, fetch: false) - - assert object.data["content"] == - "https://example.org is the site of @#{other_user.nickname} #2hu" - end - - test "it posts a chat message" do - author = insert(:user) - recipient = insert(:user) - - {:ok, activity} = - CommonAPI.post_chat_message( - author, - recipient, - "a test message :firefox:" - ) - - assert activity.data["type"] == "Create" - assert activity.local - object = Object.normalize(activity, fetch: false) - - assert object.data["type"] == "ChatMessage" - assert object.data["to"] == [recipient.ap_id] - - assert object.data["content"] == - "a test message <script>alert('uuu')</script> :firefox:" - - assert object.data["emoji"] == %{ - "firefox" => "http://localhost:4001/emoji/Firefox.gif" - } - - assert Chat.get(author.id, recipient.ap_id) - assert Chat.get(recipient.id, author.ap_id) - - assert :ok == Pleroma.Web.Federator.perform(:publish, activity) - end - - test "it reject messages over the local limit" do - clear_config([:instance, :chat_limit], 2) - - author = insert(:user) - recipient = insert(:user) - - {:error, message} = - CommonAPI.post_chat_message( - author, - recipient, - "123" - ) - - assert message == :content_too_long - end - - test "it reject messages via MRF" do - clear_config([:mrf_keyword, :reject], ["GNO"]) - clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy]) - - author = insert(:user) - recipient = insert(:user) - - assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} == - CommonAPI.post_chat_message(author, recipient, "GNO/Linux") - end - end - describe "unblocking" do test "it works even without an existing block activity" do blocked = insert(:user) diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index de38a9798..402c71e77 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -1683,7 +1683,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do response = json_response_and_validate_schema(conn, 200) assert %{"id" => id, "source" => %{"privacy" => "public"}} = response - assert response["pleroma"]["chat_token"] assert response["pleroma"]["unread_notifications_count"] == 6 assert id == to_string(user.id) end diff --git a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs index e76cbc75b..90801a90a 100644 --- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs @@ -38,7 +38,6 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do "background_upload_limit" => _, "banner_upload_limit" => _, "background_image" => from_config_background, - "shout_limit" => _, "description_limit" => _ } = result diff --git a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs index 650783587..f463bfae1 100644 --- a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs @@ -52,27 +52,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert response == expected_response end - test "by default, does not contain pleroma:chat_mention" do - %{user: user, conn: conn} = oauth_access(["read:notifications"]) - other_user = insert(:user) - - {:ok, _activity} = CommonAPI.post_chat_message(other_user, user, "hey") - - result = - conn - |> get("/api/v1/notifications") - |> json_response_and_validate_schema(200) - - assert [] == result - - result = - conn - |> get("/api/v1/notifications?include_types[]=pleroma:chat_mention") - |> json_response_and_validate_schema(200) - - assert [_] = result - end - test "by default, does not contain pleroma:report" do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) diff --git a/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs index 5a3f93d2d..1335656b4 100644 --- a/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs @@ -113,7 +113,6 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do "favourite" => true, "follow" => true, "reblog" => true, - "pleroma:chat_mention" => true, "pleroma:emoji_reaction" => true } }, @@ -129,7 +128,6 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do "favourite" => true, "follow" => true, "reblog" => true, - "pleroma:chat_mention" => true, "pleroma:emoji_reaction" => true }, "endpoint" => subscription.endpoint, @@ -185,7 +183,6 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do "favourite" => true, "follow" => true, "reblog" => true, - "pleroma:chat_mention" => true, "pleroma:emoji_reaction" => true } } @@ -204,7 +201,6 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do "favourite" => false, "follow" => false, "reblog" => false, - "pleroma:chat_mention" => false, "pleroma:emoji_reaction" => false } } @@ -217,7 +213,6 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do "favourite" => false, "follow" => false, "reblog" => false, - "pleroma:chat_mention" => false, "pleroma:emoji_reaction" => false }, "endpoint" => "https://example.com/example/1234", diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs index 0f423cce8..606467fa9 100644 --- a/test/pleroma/web/mastodon_api/update_credentials_test.exs +++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs @@ -104,13 +104,6 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do assert user_data["locked"] == true end - test "updates the user's chat acceptance status", %{conn: conn} do - conn = patch(conn, "/api/v1/accounts/update_credentials", %{accepts_chat_messages: "false"}) - - assert user_data = json_response_and_validate_schema(conn, 200) - assert user_data["pleroma"]["accepts_chat_messages"] == false - end - test "updates the user's allow_following_move", %{user: user, conn: conn} do assert user.allow_following_move == true diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs index c23ffb966..8db887137 100644 --- a/test/pleroma/web/mastodon_api/views/account_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs @@ -91,8 +91,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do hide_followers_count: false, hide_follows_count: false, relationship: %{}, - skip_thread_containment: false, - accepts_chat_messages: nil + skip_thread_containment: false } } @@ -193,8 +192,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do hide_followers_count: false, hide_follows_count: false, relationship: %{}, - skip_thread_containment: false, - accepts_chat_messages: nil + skip_thread_containment: false } } diff --git a/test/pleroma/web/mastodon_api/views/notification_view_test.exs b/test/pleroma/web/mastodon_api/views/notification_view_test.exs index a22c9df1d..803b1f438 100644 --- a/test/pleroma/web/mastodon_api/views/notification_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/notification_view_test.exs @@ -6,8 +6,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do use Pleroma.DataCase alias Pleroma.Activity - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo @@ -22,7 +20,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do alias Pleroma.Web.MastodonAPI.NotificationView alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MediaProxy - alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView import Pleroma.Factory defp test_notifications_rendering(notifications, user, expected_result) do @@ -40,30 +37,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do assert expected_result == result end - test "ChatMessage notification" do - user = insert(:user) - recipient = insert(:user) - {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "what's up my dude") - - {:ok, [notification]} = Notification.create_notifications(activity) - - object = Object.normalize(activity, fetch: false) - chat = Chat.get(recipient.id, user.ap_id) - - cm_ref = MessageReference.for_chat_and_object(chat, object) - - expected = %{ - id: to_string(notification.id), - pleroma: %{is_seen: false, is_muted: false}, - type: "pleroma:chat_mention", - account: AccountView.render("show.json", %{user: user, for: recipient}), - chat_message: MessageReferenceView.render("show.json", %{chat_message_reference: cm_ref}), - created_at: Utils.to_masto_date(notification.inserted_at) - } - - test_notifications_rendering([notification], recipient, [expected]) - end - test "Mention notification" do user = insert(:user) mentioned_user = insert(:user) diff --git a/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs deleted file mode 100644 index 1114da242..000000000 --- a/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs +++ /dev/null @@ -1,453 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do - use Pleroma.Web.ConnCase - - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.Object - alias Pleroma.User - alias Pleroma.Web.ActivityPub.ActivityPub - alias Pleroma.Web.CommonAPI - - import Pleroma.Factory - - describe "POST /api/v1/pleroma/chats/:id/messages/:message_id/read" do - setup do: oauth_access(["write:chats"]) - - test "it marks one message as read", %{conn: conn, user: user} do - other_user = insert(:user) - - {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup") - {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2") - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - object = Object.normalize(create, fetch: false) - cm_ref = MessageReference.for_chat_and_object(chat, object) - - assert cm_ref.unread == true - - result = - conn - |> post("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}/read") - |> json_response_and_validate_schema(200) - - assert result["unread"] == false - - cm_ref = MessageReference.for_chat_and_object(chat, object) - - assert cm_ref.unread == false - end - end - - describe "POST /api/v1/pleroma/chats/:id/read" do - setup do: oauth_access(["write:chats"]) - - test "given a `last_read_id`, it marks everything until then as read", %{ - conn: conn, - user: user - } do - other_user = insert(:user) - - {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup") - {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2") - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - object = Object.normalize(create, fetch: false) - cm_ref = MessageReference.for_chat_and_object(chat, object) - - assert cm_ref.unread == true - - result = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/pleroma/chats/#{chat.id}/read", %{"last_read_id" => cm_ref.id}) - |> json_response_and_validate_schema(200) - - assert result["unread"] == 1 - - cm_ref = MessageReference.for_chat_and_object(chat, object) - - assert cm_ref.unread == false - end - end - - describe "POST /api/v1/pleroma/chats/:id/messages" do - setup do: oauth_access(["write:chats"]) - - test "it posts a message to the chat", %{conn: conn, user: user} do - other_user = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - - result = - conn - |> put_req_header("content-type", "application/json") - |> put_req_header("idempotency-key", "123") - |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "Hallo!!"}) - |> json_response_and_validate_schema(200) - - assert result["content"] == "Hallo!!" - assert result["chat_id"] == chat.id |> to_string() - assert result["idempotency_key"] == "123" - end - - test "it fails if there is no content", %{conn: conn, user: user} do - other_user = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - - result = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/pleroma/chats/#{chat.id}/messages") - |> json_response_and_validate_schema(400) - - assert %{"error" => "no_content"} == result - end - - test "it works with an attachment", %{conn: conn, user: user} do - clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local) - clear_config([Pleroma.Uploaders.Local, :uploads], "uploads") - - file = %Plug.Upload{ - content_type: "image/jpeg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) - - other_user = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - - result = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{ - "media_id" => to_string(upload.id) - }) - |> json_response_and_validate_schema(200) - - assert result["attachment"] - end - - test "gets MRF reason when rejected", %{conn: conn, user: user} do - clear_config([:mrf_keyword, :reject], ["GNO"]) - clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy]) - - other_user = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - - result = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "GNO/Linux"}) - |> json_response_and_validate_schema(422) - - assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} == result - end - end - - describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do - setup do: oauth_access(["write:chats"]) - - test "it deletes a message from the chat", %{conn: conn, user: user} do - recipient = insert(:user) - - {:ok, message} = - CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend") - - {:ok, other_message} = CommonAPI.post_chat_message(recipient, user, "nico nico ni") - - object = Object.normalize(message, fetch: false) - - chat = Chat.get(user.id, recipient.ap_id) - - cm_ref = MessageReference.for_chat_and_object(chat, object) - - # Deleting your own message removes the message and the reference - result = - conn - |> put_req_header("content-type", "application/json") - |> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}") - |> json_response_and_validate_schema(200) - - assert result["id"] == cm_ref.id - refute MessageReference.get_by_id(cm_ref.id) - assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id) - - # Deleting other people's messages just removes the reference - object = Object.normalize(other_message, fetch: false) - cm_ref = MessageReference.for_chat_and_object(chat, object) - - result = - conn - |> put_req_header("content-type", "application/json") - |> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}") - |> json_response_and_validate_schema(200) - - assert result["id"] == cm_ref.id - refute MessageReference.get_by_id(cm_ref.id) - assert Object.get_by_id(object.id) - end - end - - describe "GET /api/v1/pleroma/chats/:id/messages" do - setup do: oauth_access(["read:chats"]) - - test "it paginates", %{conn: conn, user: user} do - recipient = insert(:user) - - Enum.each(1..30, fn _ -> - {:ok, _} = CommonAPI.post_chat_message(user, recipient, "hey") - end) - - chat = Chat.get(user.id, recipient.ap_id) - - response = get(conn, "/api/v1/pleroma/chats/#{chat.id}/messages") - result = json_response_and_validate_schema(response, 200) - - [next, prev] = get_resp_header(response, "link") |> hd() |> String.split(", ") - api_endpoint = "/api/v1/pleroma/chats/" - - assert String.match?( - next, - ~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*; rel=\"next\"$) - ) - - assert String.match?( - prev, - ~r(#{api_endpoint}.*/messages\?limit=\d+&min_id=.*; rel=\"prev\"$) - ) - - assert length(result) == 20 - - response = - get(conn, "/api/v1/pleroma/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}") - - result = json_response_and_validate_schema(response, 200) - [next, prev] = get_resp_header(response, "link") |> hd() |> String.split(", ") - - assert String.match?( - next, - ~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*; rel=\"next\"$) - ) - - assert String.match?( - prev, - ~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*&min_id=.*; rel=\"prev\"$) - ) - - assert length(result) == 10 - end - - test "it returns the messages for a given chat", %{conn: conn, user: user} do - other_user = insert(:user) - third_user = insert(:user) - - {:ok, _} = CommonAPI.post_chat_message(user, other_user, "hey") - {:ok, _} = CommonAPI.post_chat_message(user, third_user, "hey") - {:ok, _} = CommonAPI.post_chat_message(user, other_user, "how are you?") - {:ok, _} = CommonAPI.post_chat_message(other_user, user, "fine, how about you?") - - chat = Chat.get(user.id, other_user.ap_id) - - result = - conn - |> get("/api/v1/pleroma/chats/#{chat.id}/messages") - |> json_response_and_validate_schema(200) - - result - |> Enum.each(fn message -> - assert message["chat_id"] == chat.id |> to_string() - end) - - assert length(result) == 3 - - # Trying to get the chat of a different user - other_user_chat = Chat.get(other_user.id, user.ap_id) - - conn - |> get("/api/v1/pleroma/chats/#{other_user_chat.id}/messages") - |> json_response_and_validate_schema(404) - end - end - - describe "POST /api/v1/pleroma/chats/by-account-id/:id" do - setup do: oauth_access(["write:chats"]) - - test "it creates or returns a chat", %{conn: conn} do - other_user = insert(:user) - - result = - conn - |> post("/api/v1/pleroma/chats/by-account-id/#{other_user.id}") - |> json_response_and_validate_schema(200) - - assert result["id"] - end - end - - describe "GET /api/v1/pleroma/chats/:id" do - setup do: oauth_access(["read:chats"]) - - test "it returns a chat", %{conn: conn, user: user} do - other_user = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) - - result = - conn - |> get("/api/v1/pleroma/chats/#{chat.id}") - |> json_response_and_validate_schema(200) - - assert result["id"] == to_string(chat.id) - end - end - - describe "GET /api/v2/pleroma/chats" do - setup do: oauth_access(["read:chats"]) - - test "it does not return chats with deleted users", %{conn: conn, user: user} do - recipient = insert(:user) - {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id) - - Pleroma.Repo.delete(recipient) - User.invalidate_cache(recipient) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - assert length(result) == 0 - end - - test "it does not return chats with users you blocked", %{conn: conn, user: user} do - recipient = insert(:user) - - {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - assert length(result) == 1 - - User.block(user, recipient) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - assert length(result) == 0 - end - - test "it does not return chats with users you muted", %{conn: conn, user: user} do - recipient = insert(:user) - - {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - assert length(result) == 1 - - User.mute(user, recipient) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - assert length(result) == 0 - - result = - conn - |> get("/api/v2/pleroma/chats?with_muted=true") - |> json_response_and_validate_schema(200) - - assert length(result) == 1 - end - - test "it paginates chats", %{conn: conn, user: user} do - Enum.each(1..30, fn _ -> - recipient = insert(:user) - {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id) - end) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - assert length(result) == 20 - last_id = List.last(result)["id"] - - result = - conn - |> get("/api/v2/pleroma/chats?max_id=#{last_id}") - |> json_response_and_validate_schema(200) - - assert length(result) == 10 - end - - test "it return a list of chats the current user is participating in, in descending order of updates", - %{conn: conn, user: user} do - har = insert(:user) - jafnhar = insert(:user) - tridi = insert(:user) - - {:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id) - {:ok, chat_1} = time_travel(chat_1, -3) - {:ok, chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id) - {:ok, _chat_2} = time_travel(chat_2, -2) - {:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id) - {:ok, chat_3} = time_travel(chat_3, -1) - - # bump the second one - {:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - ids = Enum.map(result, & &1["id"]) - - assert ids == [ - chat_2.id |> to_string(), - chat_3.id |> to_string(), - chat_1.id |> to_string() - ] - end - - test "it is not affected by :restrict_unauthenticated setting (issue #1973)", %{ - conn: conn, - user: user - } do - clear_config([:restrict_unauthenticated, :profiles, :local], true) - clear_config([:restrict_unauthenticated, :profiles, :remote], true) - - user2 = insert(:user) - user3 = insert(:user, local: false) - - {:ok, _chat_12} = Chat.get_or_create(user.id, user2.ap_id) - {:ok, _chat_13} = Chat.get_or_create(user.id, user3.ap_id) - - result = - conn - |> get("/api/v2/pleroma/chats") - |> json_response_and_validate_schema(200) - - account_ids = Enum.map(result, &get_in(&1, ["account", "id"])) - assert Enum.sort(account_ids) == Enum.sort([user2.id, user3.id]) - end - end -end diff --git a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs deleted file mode 100644 index 6deaa2102..000000000 --- a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs +++ /dev/null @@ -1,75 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do - use Pleroma.DataCase - - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.Object - alias Pleroma.Web.ActivityPub.ActivityPub - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView - - import Pleroma.Factory - - test "it displays a chat message" do - user = insert(:user) - recipient = insert(:user) - - file = %Plug.Upload{ - content_type: "image/jpeg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) - - {:ok, activity} = - CommonAPI.post_chat_message(user, recipient, "kippis :firefox:", idempotency_key: "123") - - chat = Chat.get(user.id, recipient.ap_id) - - object = Object.normalize(activity, fetch: false) - - cm_ref = MessageReference.for_chat_and_object(chat, object) - - chat_message = MessageReferenceView.render("show.json", chat_message_reference: cm_ref) - - assert chat_message[:id] == cm_ref.id - assert chat_message[:content] == "kippis :firefox:" - assert chat_message[:account_id] == user.id - assert chat_message[:chat_id] - assert chat_message[:created_at] - assert chat_message[:unread] == false - assert match?([%{shortcode: "firefox"}], chat_message[:emojis]) - assert chat_message[:idempotency_key] == "123" - - clear_config([:rich_media, :enabled], true) - - Tesla.Mock.mock_global(fn - %{url: "https://example.com/ogp"} -> - %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")} - end) - - {:ok, activity} = - CommonAPI.post_chat_message(recipient, user, "gkgkgk https://example.com/ogp", - media_id: upload.id - ) - - object = Object.normalize(activity, fetch: false) - - cm_ref = MessageReference.for_chat_and_object(chat, object) - - chat_message_two = MessageReferenceView.render("show.json", chat_message_reference: cm_ref) - - assert chat_message_two[:id] == cm_ref.id - assert chat_message_two[:content] == object.data["content"] - assert chat_message_two[:account_id] == recipient.id - assert chat_message_two[:chat_id] == chat_message[:chat_id] - assert chat_message_two[:attachment] - assert chat_message_two[:unread] == true - assert chat_message_two[:card] - end -end diff --git a/test/pleroma/web/pleroma_api/views/chat_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_view_test.exs deleted file mode 100644 index 5456c2de0..000000000 --- a/test/pleroma/web/pleroma_api/views/chat_view_test.exs +++ /dev/null @@ -1,49 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.PleromaAPI.ChatViewTest do - use Pleroma.DataCase, async: true - - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference - alias Pleroma.Object - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.CommonAPI.Utils - alias Pleroma.Web.MastodonAPI.AccountView - alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView - alias Pleroma.Web.PleromaAPI.ChatView - - import Pleroma.Factory - - test "it represents a chat" do - user = insert(:user) - recipient = insert(:user) - - {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id) - - represented_chat = ChatView.render("show.json", chat: chat) - - assert represented_chat == %{ - id: "#{chat.id}", - account: - AccountView.render("show.json", user: recipient, skip_visibility_check: true), - unread: 0, - last_message: nil, - updated_at: Utils.to_masto_date(chat.updated_at) - } - - {:ok, chat_message_creation} = CommonAPI.post_chat_message(user, recipient, "hello") - - chat_message = Object.normalize(chat_message_creation, fetch: false) - - {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id) - - represented_chat = ChatView.render("show.json", chat: chat) - - cm_ref = MessageReference.for_chat_and_object(chat, chat_message) - - assert represented_chat[:last_message] == - MessageReferenceView.render("show.json", chat_message_reference: cm_ref) - end -end diff --git a/test/pleroma/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs index b3ca1a337..9100433ae 100644 --- a/test/pleroma/web/push/impl_test.exs +++ b/test/pleroma/web/push/impl_test.exs @@ -7,10 +7,8 @@ defmodule Pleroma.Web.Push.ImplTest do import Pleroma.Factory - alias Pleroma.Notification alias Pleroma.Object alias Pleroma.User - alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.CommonAPI alias Pleroma.Web.Push.Impl alias Pleroma.Web.Push.Subscription @@ -216,46 +214,6 @@ defmodule Pleroma.Web.Push.ImplTest do end describe "build_content/3" do - test "builds content for chat messages" do - user = insert(:user) - recipient = insert(:user) - - {:ok, chat} = CommonAPI.post_chat_message(user, recipient, "hey") - object = Object.normalize(chat, fetch: false) - [notification] = Notification.for_user(recipient) - - res = Impl.build_content(notification, user, object) - - assert res == %{ - body: "@#{user.nickname}: hey", - title: "New Chat Message" - } - end - - test "builds content for chat messages with no content" do - user = insert(:user) - recipient = insert(:user) - - file = %Plug.Upload{ - content_type: "image/jpeg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) - - {:ok, chat} = CommonAPI.post_chat_message(user, recipient, nil, media_id: upload.id) - object = Object.normalize(chat, fetch: false) - [notification] = Notification.for_user(recipient) - - res = Impl.build_content(notification, user, object) - - assert res == %{ - body: "@#{user.nickname}: (Attachment)", - title: "New Chat Message" - } - end - test "hides contents of notifications when option enabled" do user = insert(:user, nickname: "Bob") diff --git a/test/pleroma/web/shout_channel_test.exs b/test/pleroma/web/shout_channel_test.exs deleted file mode 100644 index 5c86efe9f..000000000 --- a/test/pleroma/web/shout_channel_test.exs +++ /dev/null @@ -1,41 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ShoutChannelTest do - use Pleroma.Web.ChannelCase - alias Pleroma.Web.ShoutChannel - alias Pleroma.Web.UserSocket - - import Pleroma.Factory - - setup do - user = insert(:user) - - {:ok, _, socket} = - socket(UserSocket, "", %{user_name: user.nickname}) - |> subscribe_and_join(ShoutChannel, "chat:public") - - {:ok, socket: socket} - end - - test "it broadcasts a message", %{socket: socket} do - push(socket, "new_msg", %{"text" => "why is tenshi eating a corndog so cute?"}) - assert_broadcast("new_msg", %{text: "why is tenshi eating a corndog so cute?"}) - end - - describe "message lengths" do - setup do: clear_config([:shout, :limit]) - - test "it ignores messages of length zero", %{socket: socket} do - push(socket, "new_msg", %{"text" => ""}) - refute_broadcast("new_msg", %{text: ""}) - end - - test "it ignores messages above a certain length", %{socket: socket} do - clear_config([:shout, :limit], 2) - push(socket, "new_msg", %{"text" => "123"}) - refute_broadcast("new_msg", %{text: "123"}) - end - end -end diff --git a/test/pleroma/web/streamer_test.exs b/test/pleroma/web/streamer_test.exs index b2941a62c..841db0e91 100644 --- a/test/pleroma/web/streamer_test.exs +++ b/test/pleroma/web/streamer_test.exs @@ -7,15 +7,11 @@ defmodule Pleroma.Web.StreamerTest do import Pleroma.Factory - alias Pleroma.Chat - alias Pleroma.Chat.MessageReference alias Pleroma.Conversation.Participation alias Pleroma.List - alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.CommonAPI alias Pleroma.Web.Streamer - alias Pleroma.Web.StreamerView @moduletag needs_streamer: true, capture_log: true @@ -80,20 +76,16 @@ defmodule Pleroma.Web.StreamerTest do expected_user_topic = "user:#{user.id}" expected_notification_topic = "user:notification:#{user.id}" expected_direct_topic = "direct:#{user.id}" - expected_pleroma_chat_topic = "user:pleroma_chat:#{user.id}" for valid_user_token <- [read_oauth_token, read_statuses_token] do assert {:ok, ^expected_user_topic} = Streamer.get_topic("user", user, valid_user_token) assert {:ok, ^expected_direct_topic} = Streamer.get_topic("direct", user, valid_user_token) - - assert {:ok, ^expected_pleroma_chat_topic} = - Streamer.get_topic("user:pleroma_chat", user, valid_user_token) end for invalid_user_token <- [read_notifications_token, badly_scoped_token], - user_topic <- ["user", "direct", "user:pleroma_chat"] do + user_topic <- ["user", "direct"] do assert {:error, :unauthorized} = Streamer.get_topic(user_topic, user, invalid_user_token) end @@ -257,66 +249,6 @@ defmodule Pleroma.Web.StreamerTest do refute Streamer.filtered_by_user?(user, notify) end - test "it sends chat messages to the 'user:pleroma_chat' stream", %{ - user: user, - token: oauth_token - } do - other_user = insert(:user) - - {:ok, create_activity} = - CommonAPI.post_chat_message(other_user, user, "hey cirno", idempotency_key: "123") - - object = Object.normalize(create_activity, fetch: false) - chat = Chat.get(user.id, other_user.ap_id) - cm_ref = MessageReference.for_chat_and_object(chat, object) - cm_ref = %{cm_ref | chat: chat, object: object} - - Streamer.get_topic_and_add_socket("user:pleroma_chat", user, oauth_token) - Streamer.stream("user:pleroma_chat", {user, cm_ref}) - - text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}) - - assert text =~ "hey cirno" - assert_receive {:text, ^text} - end - - test "it sends chat messages to the 'user' stream", %{user: user, token: oauth_token} do - other_user = insert(:user) - - {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno") - object = Object.normalize(create_activity, fetch: false) - chat = Chat.get(user.id, other_user.ap_id) - cm_ref = MessageReference.for_chat_and_object(chat, object) - cm_ref = %{cm_ref | chat: chat, object: object} - - Streamer.get_topic_and_add_socket("user", user, oauth_token) - Streamer.stream("user", {user, cm_ref}) - - text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}) - - assert text =~ "hey cirno" - assert_receive {:text, ^text} - end - - test "it sends chat message notifications to the 'user:notification' stream", %{ - user: user, - token: oauth_token - } do - other_user = insert(:user) - - {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey") - - notify = - Repo.get_by(Pleroma.Notification, user_id: user.id, activity_id: create_activity.id) - |> Repo.preload(:activity) - - Streamer.get_topic_and_add_socket("user:notification", user, oauth_token) - Streamer.stream("user:notification", notify) - - assert_receive {:render_with_user, _, _, ^notify} - refute Streamer.filtered_by_user?(user, notify) - end - test "it doesn't send notify to the 'user:notification' stream when a user is blocked", %{ user: user, token: oauth_token