summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md96
-rw-r--r--config/description.exs346
-rw-r--r--docs/api/admin_api.md24
-rw-r--r--docs/api/differences_in_mastoapi_responses.md4
-rw-r--r--lib/pleroma/constants.ex12
-rw-r--r--lib/pleroma/docs/markdown.ex26
-rw-r--r--lib/pleroma/object.ex18
-rw-r--r--lib/pleroma/object/fetcher.ex38
-rw-r--r--lib/pleroma/user/info.ex14
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex10
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex32
-rw-r--r--lib/pleroma/web/admin_api/admin_api_controller.ex22
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex4
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex14
-rw-r--r--lib/pleroma/web/router.ex2
-rw-r--r--mix.exs7
-rw-r--r--mix.lock2
-rw-r--r--test/fixtures/tesla_mock/poll_modified.json1
-rw-r--r--test/fixtures/tesla_mock/poll_original.json1
-rw-r--r--test/fixtures/tesla_mock/rin.json1
-rw-r--r--test/object_test.exs109
-rw-r--r--test/support/http_request_mock.ex4
-rw-r--r--test/test_helper.exs5
-rw-r--r--test/web/activity_pub/views/user_view_test.exs24
-rw-r--r--test/web/admin_api/admin_api_controller_test.exs46
-rw-r--r--test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs16
-rw-r--r--test/web/mastodon_api/views/account_view_test.exs31
-rw-r--r--test/web/twitter_api/util_controller_test.exs105
28 files changed, 627 insertions, 387 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 584386136..906aa985e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,14 +4,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
+### Added
+- Refreshing poll results for remote polls
+### Changed
+- **Breaking:** Elixir >=1.8 is now required (was >= 1.7)
+- Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings)
+- Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler
+- Admin API: Return `total` when querying for reports
+
+## [1.1.0] - 2019-??-??
### Security
-- OStatus: eliminate the possibility of a protocol downgrade attack.
-- OStatus: prevent following locked accounts, bypassing the approval process.
- Mastodon API: respect post privacy in `/api/v1/statuses/:id/{favourited,reblogged}_by`
### Removed
- **Breaking:** GNU Social API with Qvitter extensions support
-- **Breaking:** ActivityPub: The `accept_blocks` configuration setting.
- Emoji: Remove longfox emojis.
- Remove `Reply-To` header from report emails for admins.
@@ -19,9 +25,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Breaking:** Configuration: A setting to explicitly disable the mailer was added, defaulting to true, if you are using a mailer add `config :pleroma, Pleroma.Emails.Mailer, enabled: true` to your config
- **Breaking:** Configuration: `/media/` is now removed when `base_url` is configured, append `/media/` to your `base_url` config to keep the old behaviour if desired
- **Breaking:** `/api/pleroma/notifications/read` is moved to `/api/v1/pleroma/notifications/read` and now supports `max_id` and responds with Mastodon API entities.
+- **Breaking:** `/api/pleroma/admin/users/invite_token` now uses `POST`, changed accepted params and returns full invite in json instead of only token string.
+- Configuration: added `config/description.exs`, from which `docs/config.md` is generated
- Configuration: OpenGraph and TwitterCard providers enabled by default
- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
-- Configuration: added `config/description.exs`, from which `docs/config.md` is generated
+- Mastodon API: `pleroma.thread_muted` key in the Status entity
- Federation: Return 403 errors when trying to request pages from a user's follower/following collections if they have `hide_followers`/`hide_follows` set
- NodeInfo: Return `skipThreadContainment` in `metadata` for the `skip_thread_containment` option
- NodeInfo: Return `mailerEnabled` in `metadata`
@@ -30,24 +38,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- AdminAPI: Add "godmode" while fetching user statuses (i.e. admin can see private statuses)
- Improve digest email template
– Pagination: (optional) return `total` alongside with `items` when paginating
-- Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings)
-- Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler
-- Admin API: Return `total` when querying for reports
### Fixed
- Following from Osada
-- Not being able to pin unlisted posts
-- Objects being re-embedded to activities after being updated (e.g faved/reposted). Running 'mix pleroma.database prune_objects' again is advised.
- Favorites timeline doing database-intensive queries
- Metadata rendering errors resulting in the entire page being inaccessible
- `federation_incoming_replies_max_depth` option being ignored in certain cases
-- Federation/MediaProxy not working with instances that have wrong certificate order
- Mastodon API: Handling of search timeouts (`/api/v1/search` and `/api/v2/search`)
- Mastodon API: Misskey's endless polls being unable to render
- Mastodon API: Embedded relationships not being properly rendered in the Account entity of Status entity
- Mastodon API: Notifications endpoint crashing if one notification failed to render
-- Mastodon API: follower/following counters not being nullified, when `hide_follows`/`hide_followers` is set
-- Mastodon API: `muted` in the Status entity, using author's account to determine if the tread was muted
- Mastodon API: Add `account_id`, `type`, `offset`, and `limit` to search API (`/api/v1/search` and `/api/v2/search`)
- Mastodon API, streaming: Fix filtering of notifications based on blocks/mutes/thread mutes
- ActivityPub C2S: follower/following collection pages being inaccessible even when authentifucated if `hide_followers`/ `hide_follows` was set
@@ -55,15 +55,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Rich Media: Parser failing when no TTL can be found by image TTL setters
- Rich Media: The crawled URL is now spliced into the rich media data.
- ActivityPub S2S: sharedInbox usage has been mostly aligned with the rules in the AP specification.
-- ActivityPub S2S: remote user deletions now work the same as local user deletions.
-- ActivityPub S2S: POST requests are now signed with `(request-target)` pseudo-header.
-- Not being able to access the Mastodon FE login page on private instances
-- Invalid SemVer version generation, when the current branch does not have commits ahead of tag/checked out on a tag
- Pleroma.Upload base_url was not automatically whitelisted by MediaProxy. Now your custom CDN or file hosting will be accessed directly as expected.
- Report email not being sent to admins when the reporter is a remote user
-- MRF: ensure that subdomain_match calls are case-insensitive
- Reverse Proxy limiting `max_body_length` was incorrectly defined and only checked `Content-Length` headers which may not be sufficient in some circumstances
-- MRF: fix use of unserializable keyword lists in describe() implementations
- ActivityPub: Deactivated user deletion
- ActivityPub: Fix `/users/:nickname/inbox` crashing without an authenticated user
- MRF: fix ability to follow a relay when AntiFollowbotPolicy was enabled
@@ -74,16 +68,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: all status JSON responses contain a `pleroma.expires_at` item which states when an activity will expire. The value is only shown to the user who created the activity. To everyone else it's empty.
- Configuration: `ActivityExpiration.enabled` controls whether expired activites will get deleted at the appropriate time. Enabled by default.
- Conversations: Add Pleroma-specific conversation endpoints and status posting extensions. Run the `bump_all_conversations` task again to create the necessary data.
-- **Breaking:** MRF describe API, which adds support for exposing configuration information about MRF policies to NodeInfo.
- Custom modules will need to be updated by adding, at the very least, `def describe, do: {:ok, %{}}` to the MRF policy modules.
- MRF: Support for priming the mediaproxy cache (`Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`)
- MRF: Support for excluding specific domains from Transparency.
- MRF: Support for filtering posts based on who they mention (`Pleroma.Web.ActivityPub.MRF.MentionPolicy`)
-- MRF: Support for filtering posts based on ActivityStreams vocabulary (`Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`)
-- MRF (Simple Policy): Support for wildcard domains.
-- Support for wildcard domains in user domain blocks setting.
-- Configuration: `quarantined_instances` support wildcard domains.
-- Configuration: `federation_incoming_replies_max_depth` option
- Mastodon API: Support for the [`tagged` filter](https://github.com/tootsuite/mastodon/pull/9755) in [`GET /api/v1/accounts/:id/statuses`](https://docs.joinmastodon.org/api/rest/accounts/#get-api-v1-accounts-id-statuses)
- Mastodon API, streaming: Add support for passing the token in the `Sec-WebSocket-Protocol` header
- Mastodon API, extension: Ability to reset avatar, profile banner, and background
@@ -95,6 +82,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: added `/auth/password` endpoint for password reset with rate limit.
- Mastodon API: /api/v1/accounts/:id/statuses now supports nicknames or user id
- Mastodon API: Improve support for the user profile custom fields
+- Mastodon API: follower/following counters are nullified when `hide_follows`/`hide_followers` and `hide_follows_count`/`hide_followers_count` are set
- Admin API: Return users' tags when querying reports
- Admin API: Return avatar and display name when querying users
- Admin API: Allow querying user by ID
@@ -111,9 +99,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Admin API: Endpoint for fetching latest user's statuses
- Pleroma API: Add `/api/v1/pleroma/accounts/confirmation_resend?email=<email>` for resending account confirmation.
- Pleroma API: Email change endpoint.
-- Relays: Added a task to list relay subscriptions.
-- Mix Tasks: `mix pleroma.database fix_likes_collections`
-- Federation: Remove `likes` from objects.
- Admin API: Added moderation log
- Web response cache (currently, enabled for ActivityPub)
- Mastodon API: Added an endpoint to get multiple statuses by IDs (`GET /api/v1/statuses/?ids[]=1&ids[]=2`)
@@ -124,6 +109,61 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- RichMedia: parsers and their order are configured in `rich_media` config.
- RichMedia: add the rich media ttl based on image expiration time.
+## [1.0.6] - 2019-08-14
+### Fixed
+- MRF: fix use of unserializable keyword lists in describe() implementations
+- ActivityPub S2S: POST requests are now signed with `(request-target)` pseudo-header.
+
+## [1.0.5] - 2019-08-13
+### Fixed
+- Mastodon API: follower/following counters not being nullified, when `hide_follows`/`hide_followers` is set
+- Mastodon API: `muted` in the Status entity, using author's account to determine if the thread was muted
+- Mastodon API: return the actual profile URL in the Account entity's `url` property when appropriate
+- Templates: properly style anchor tags
+- Objects being re-embedded to activities after being updated (e.g faved/reposted). Running 'mix pleroma.database prune_objects' again is advised.
+- Not being able to access the Mastodon FE login page on private instances
+- MRF: ensure that subdomain_match calls are case-insensitive
+- Fix internal server error when using the healthcheck API.
+
+### Added
+- **Breaking:** MRF describe API, which adds support for exposing configuration information about MRF policies to NodeInfo.
+ Custom modules will need to be updated by adding, at the very least, `def describe, do: {:ok, %{}}` to the MRF policy modules.
+- Relays: Added a task to list relay subscriptions.
+- MRF: Support for filtering posts based on ActivityStreams vocabulary (`Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`)
+- MRF (Simple Policy): Support for wildcard domains.
+- Support for wildcard domains in user domain blocks setting.
+- Configuration: `quarantined_instances` support wildcard domains.
+- Mix Tasks: `mix pleroma.database fix_likes_collections`
+- Configuration: `federation_incoming_replies_max_depth` option
+
+### Removed
+- Federation: Remove `likes` from objects.
+- **Breaking:** ActivityPub: The `accept_blocks` configuration setting.
+
+## [1.0.4] - 2019-08-01
+### Fixed
+- Invalid SemVer version generation, when the current branch does not have commits ahead of tag/checked out on a tag
+
+## [1.0.3] - 2019-07-31
+### Security
+- OStatus: eliminate the possibility of a protocol downgrade attack.
+- OStatus: prevent following locked accounts, bypassing the approval process.
+- TwitterAPI: use CommonAPI to handle remote follows instead of OStatus.
+
+## [1.0.2] - 2019-07-28
+### Fixed
+- Not being able to pin unlisted posts
+- Mastodon API: represent poll IDs as strings
+- MediaProxy: fix matching filenames
+- MediaProxy: fix filename encoding
+- Migrations: fix a sporadic migration failure
+- Metadata rendering errors resulting in the entire page being inaccessible
+- Federation/MediaProxy not working with instances that have wrong certificate order
+- ActivityPub S2S: remote user deletions now work the same as local user deletions.
+
+### Changed
+- Configuration: OpenGraph and TwitterCard providers enabled by default
+- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
## [1.0.1] - 2019-07-14
### Security
diff --git a/config/description.exs b/config/description.exs
index 32d36d6d6..65ea6bf01 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -39,11 +39,7 @@ config :pleroma, :config_description, [
key: :link_name,
type: :boolean,
description:
- "If enabled, a name parameter will be added to the url of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`",
- suggestions: [
- true,
- false
- ]
+ "If enabled, a name parameter will be added to the url of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`"
},
%{
key: :base_url,
@@ -57,11 +53,7 @@ config :pleroma, :config_description, [
key: :proxy_remote,
type: :boolean,
description:
- "If enabled, requests to media stored using a remote uploader will be proxied instead of being redirected.",
- suggestions: [
- true,
- false
- ]
+ "If enabled, requests to media stored using a remote uploader will be proxied instead of being redirected."
},
%{
key: :proxy_opts,
@@ -117,8 +109,7 @@ config :pleroma, :config_description, [
type: :string,
description:
"If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc." <>
- " For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in public_endpoint.",
- suggestions: [""]
+ " For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in public_endpoint."
}
]
},
@@ -190,11 +181,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Allow/disallow send emails",
- suggestions: [
- true,
- false
- ]
+ description: "Allow/disallow send emails"
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
@@ -221,8 +208,7 @@ config :pleroma, :config_description, [
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :ssl,
type: :boolean,
- description: "`Swoosh.Adapters.SMTP` adapter specific setting",
- suggestions: [true, false]
+ description: "`Swoosh.Adapters.SMTP` adapter specific setting"
},
%{
group: {:subgroup, Swoosh.Adapters.SMTP},
@@ -256,8 +242,7 @@ config :pleroma, :config_description, [
group: {:subgroup, Swoosh.Adapters.SMTP},
key: :no_mx_lookups,
type: :boolean,
- description: "`Swoosh.Adapters.SMTP` adapter specific setting",
- suggestions: [true, false]
+ description: "`Swoosh.Adapters.SMTP` adapter specific setting"
},
%{
group: {:subgroup, Swoosh.Adapters.Sendgrid},
@@ -284,8 +269,7 @@ config :pleroma, :config_description, [
group: {:subgroup, Swoosh.Adapters.Sendmail},
key: :qmail,
type: :boolean,
- description: "`Swoosh.Adapters.Sendmail` adapter specific setting",
- suggestions: [true, false]
+ description: "`Swoosh.Adapters.Sendmail` adapter specific setting"
},
%{
group: {:subgroup, Swoosh.Adapters.Mandrill},
@@ -375,22 +359,19 @@ config :pleroma, :config_description, [
group: {:subgroup, Swoosh.Adapters.SocketLabs},
key: :server_id,
type: :string,
- description: "`Swoosh.Adapters.SocketLabs` adapter specific setting",
- suggestions: [""]
+ description: "`Swoosh.Adapters.SocketLabs` adapter specific setting"
},
%{
group: {:subgroup, Swoosh.Adapters.SocketLabs},
key: :api_key,
type: :string,
- description: "`Swoosh.Adapters.SocketLabs` adapter specific setting",
- suggestions: [""]
+ description: "`Swoosh.Adapters.SocketLabs` adapter specific setting"
},
%{
group: {:subgroup, Swoosh.Adapters.Gmail},
key: :access_token,
type: :string,
- description: "`Swoosh.Adapters.Gmail` adapter specific setting",
- suggestions: [""]
+ description: "`Swoosh.Adapters.Gmail` adapter specific setting"
}
]
},
@@ -553,38 +534,22 @@ config :pleroma, :config_description, [
%{
key: :registrations_open,
type: :boolean,
- description: "Enable registrations for anyone, invitations can be enabled when false",
- suggestions: [
- true,
- false
- ]
+ description: "Enable registrations for anyone, invitations can be enabled when false"
},
%{
key: :invites_enabled,
type: :boolean,
- description: "Enable user invitations for admins (depends on registrations_open: false)",
- suggestions: [
- true,
- false
- ]
+ description: "Enable user invitations for admins (depends on registrations_open: false)"
},
%{
key: :account_activation_required,
type: :boolean,
- description: "Require users to confirm their emails before signing in",
- suggestions: [
- true,
- false
- ]
+ description: "Require users to confirm their emails before signing in"
},
%{
key: :federating,
type: :boolean,
- description: "Enable federation with other instances",
- suggestions: [
- true,
- false
- ]
+ description: "Enable federation with other instances"
},
%{
key: :federation_incoming_replies_max_depth,
@@ -618,11 +583,7 @@ config :pleroma, :config_description, [
%{
key: :allow_relay,
type: :boolean,
- description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance",
- suggestions: [
- true,
- false
- ]
+ description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance"
},
%{
key: :rewrite_policy,
@@ -638,11 +599,7 @@ config :pleroma, :config_description, [
type: :boolean,
description:
"Makes the client API in authentificated mode-only except for user-profiles." <>
- " Useful for disabling the Local Timeline and The Whole Known Network",
- suggestions: [
- true,
- false
- ]
+ " Useful for disabling the Local Timeline and The Whole Known Network"
},
%{
key: :quarantined_instances,
@@ -658,11 +615,7 @@ config :pleroma, :config_description, [
key: :managed_config,
type: :boolean,
description:
- "Whenether the config for pleroma-fe is configured in this config or in static/config.json",
- suggestions: [
- true,
- false
- ]
+ "Whenether the config for pleroma-fe is configured in this config or in static/config.json"
},
%{
key: :static_dir,
@@ -689,11 +642,7 @@ config :pleroma, :config_description, [
key: :mrf_transparency,
type: :boolean,
description:
- "Make the content of your Message Rewrite Facility settings public (via nodeinfo)",
- suggestions: [
- true,
- false
- ]
+ "Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
},
%{
key: :mrf_transparency_exclusions,
@@ -709,11 +658,7 @@ config :pleroma, :config_description, [
type: :boolean,
description:
"Set to true to use extended local nicknames format (allows underscores/dashes)." <>
- " This will break federation with older software for theses nicknames",
- suggestions: [
- true,
- false
- ]
+ " This will break federation with older software for theses nicknames"
},
%{
key: :max_pinned_statuses,
@@ -741,11 +686,7 @@ config :pleroma, :config_description, [
key: :no_attachment_links,
type: :boolean,
description:
- "Set to true to disable automatically adding attachment link text to statuses",
- suggestions: [
- true,
- false
- ]
+ "Set to true to disable automatically adding attachment link text to statuses"
},
%{
key: :welcome_message,
@@ -780,20 +721,12 @@ config :pleroma, :config_description, [
description:
"If set to true, only mentions at the beginning of a post will be used to address people in direct messages." <>
" This is to prevent accidental mentioning of people when talking about them (e.g. \"@friend hey i really don't like @enemy\")." <>
- " Default: false",
- suggestions: [
- true,
- false
- ]
+ " Default: false"
},
%{
key: :healthcheck,
type: :boolean,
- description: "If set to true, system data will be shown on /api/pleroma/healthcheck",
- suggestions: [
- true,
- false
- ]
+ description: "If set to true, system data will be shown on /api/pleroma/healthcheck"
},
%{
key: :remote_post_retention_days,
@@ -823,11 +756,7 @@ config :pleroma, :config_description, [
%{
key: :skip_thread_containment,
type: :boolean,
- description: "Skip filter out broken threads. The default is true",
- suggestions: [
- true,
- false
- ]
+ description: "Skip filter out broken threads. The default is true"
},
%{
key: :limit_to_local_content,
@@ -844,11 +773,7 @@ config :pleroma, :config_description, [
key: :dynamic_configuration,
type: :boolean,
description:
- "Allow transferring configuration to DB with the subsequent customization from Admin api. Defaults to `false`",
- suggestions: [
- true,
- false
- ]
+ "Allow transferring configuration to DB with the subsequent customization from Admin api. Defaults to `false`"
},
%{
key: :max_account_fields,
@@ -886,11 +811,7 @@ config :pleroma, :config_description, [
%{
key: :external_user_synchronization,
type: :boolean,
- description: "Enabling following/followers counters synchronization for external users",
- suggestions: [
- true,
- false
- ]
+ description: "Enabling following/followers counters synchronization for external users"
}
]
},
@@ -936,7 +857,6 @@ config :pleroma, :config_description, [
%{
key: :metadata,
type: {:list, :atom},
- description: "",
suggestions: [[:request_id]]
}
]
@@ -962,7 +882,6 @@ config :pleroma, :config_description, [
%{
key: :metadata,
type: {:list, :atom},
- description: "",
suggestions: [[:request_id]]
}
]
@@ -1069,48 +988,40 @@ config :pleroma, :config_description, [
%{
key: :showInstanceSpecificPanel,
type: :boolean,
- description: "Whenether to show the instance's specific panel",
- suggestions: [true, false]
+ description: "Whenether to show the instance's specific panel"
},
%{
key: :scopeOptionsEnabled,
type: :boolean,
- description: "Enable setting an notice visibility and subject/CW when posting",
- suggestions: [true, false]
+ description: "Enable setting an notice visibility and subject/CW when posting"
},
%{
key: :formattingOptionsEnabled,
type: :boolean,
description:
- "Enable setting a formatting different than plain-text (ie. HTML, Markdown) when posting, relates to :instance, allowed_post_formats",
- suggestions: [true, false]
+ "Enable setting a formatting different than plain-text (ie. HTML, Markdown) when posting, relates to :instance, allowed_post_formats"
},
%{
key: :collapseMessageWithSubject,
type: :boolean,
description:
- "When a message has a subject(aka Content Warning), collapse it by default",
- suggestions: [true, false]
+ "When a message has a subject(aka Content Warning), collapse it by default"
},
%{
key: :hidePostStats,
type: :boolean,
- description: "Hide notices statistics(repeats, favorites, ...)",
- suggestions: [true, false]
+ description: "Hide notices statistics(repeats, favorites, ...)"
},
%{
key: :hideUserStats,
type: :boolean,
description:
- "Hide profile statistics(posts, posts per day, followers, followings, ...)",
- suggestions: [true, false]
+ "Hide profile statistics(posts, posts per day, followers, followings, ...)"
},
%{
key: :scopeCopy,
type: :boolean,
- description:
- "Copy the scope (private/unlisted/public) in replies to posts by default",
- suggestions: [true, false]
+ description: "Copy the scope (private/unlisted/public) in replies to posts by default"
},
%{
key: :subjectLineBehavior,
@@ -1124,8 +1035,7 @@ config :pleroma, :config_description, [
%{
key: :alwaysShowSubjectInput,
type: :boolean,
- description: "When set to false, auto-hide the subject field when it's empty",
- suggestions: [true, false]
+ description: "When set to false, auto-hide the subject field when it's empty"
}
]
},
@@ -1142,8 +1052,7 @@ config :pleroma, :config_description, [
%{
key: :showInstanceSpecificPanel,
type: :boolean,
- description: "Whenether to show the instance's specific panel",
- suggestions: [true, false]
+ description: "Whenether to show the instance's specific panel"
}
]
}
@@ -1266,19 +1175,16 @@ config :pleroma, :config_description, [
group: :pleroma,
key: :mrf_rejectnonpublic,
type: :group,
- description: "",
children: [
%{
key: :allow_followersonly,
type: :boolean,
- description: "whether to allow followers-only posts",
- suggestions: [true, false]
+ description: "whether to allow followers-only posts"
},
%{
key: :allow_direct,
type: :boolean,
- description: "whether to allow direct messages",
- suggestions: [true, false]
+ description: "whether to allow direct messages"
}
]
},
@@ -1393,8 +1299,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Enables proxying of remote media to the instance's proxy",
- suggestions: [true, false]
+ description: "Enables proxying of remote media to the instance's proxy"
},
%{
key: :base_url,
@@ -1426,8 +1331,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Enables the gopher interface",
- suggestions: [true, false]
+ description: "Enables the gopher interface"
},
%{
key: :ip,
@@ -1537,43 +1441,36 @@ config :pleroma, :config_description, [
%{
key: :instrumenters,
type: {:list, :module},
- description: "",
suggestions: [Pleroma.Web.Endpoint.Instrumenter]
},
%{
key: :protocol,
type: :string,
- description: "",
suggestions: ["https"]
},
%{
key: :secret_key_base,
type: :string,
- description: "",
suggestions: ["aK4Abxf29xU9TTDKre9coZPUgevcVCFQJe/5xP/7Lt4BEif6idBIbjupVbOrbKxl"]
},
%{
key: :signing_salt,
type: :string,
- description: "",
suggestions: ["CqaoopA2"]
},
%{
key: :render_errors,
type: :keyword,
- description: "",
suggestions: [[view: Pleroma.Web.ErrorView, accepts: ~w(json)]],
children: [
%{
key: :view,
type: :module,
- description: "",
suggestions: [Pleroma.Web.ErrorView]
},
%{
key: :accepts,
type: {:list, :string},
- description: "",
suggestions: ["json"]
}
]
@@ -1581,33 +1478,27 @@ config :pleroma, :config_description, [
%{
key: :pubsub,
type: :keyword,
- description: "",
suggestions: [[name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2]],
children: [
%{
key: :name,
type: :module,
- description: "",
suggestions: [Pleroma.PubSub]
},
%{
key: :adapter,
type: :module,
- description: "",
suggestions: [Phoenix.PubSub.PG2]
}
]
},
%{
key: :secure_cookie_flag,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
},
%{
key: :extra_cookie_attrs,
type: {:list, :string},
- description: "",
suggestions: ["SameSite=Lax"]
}
]
@@ -1621,20 +1512,17 @@ config :pleroma, :config_description, [
%{
key: :unfollow_blocked,
type: :boolean,
- description: "Whether blocks result in people getting unfollowed",
- suggestions: [true, false]
+ description: "Whether blocks result in people getting unfollowed"
},
%{
key: :outgoing_blocks,
type: :boolean,
- description: "Whether to federate blocks to other instances",
- suggestions: [true, false]
+ description: "Whether to federate blocks to other instances"
},
%{
key: :sign_object_fetches,
type: :boolean,
- description: "Sign object fetches with HTTP signatures",
- suggestions: [true, false]
+ description: "Sign object fetches with HTTP signatures"
},
%{
key: :follow_handshake_timeout,
@@ -1653,14 +1541,12 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Whether the managed content security policy is enabled",
- suggestions: [true, false]
+ description: "Whether the managed content security policy is enabled"
},
%{
key: :sts,
type: :boolean,
- description: "Whether to additionally send a Strict-Transport-Security header",
- suggestions: [true, false]
+ description: "Whether to additionally send a Strict-Transport-Security header"
},
%{
key: :sts_max_age,
@@ -1727,8 +1613,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Whether the captcha should be shown on registration",
- suggestions: [true, false]
+ description: "Whether the captcha should be shown on registration"
},
%{
key: :method,
@@ -1778,8 +1663,7 @@ config :pleroma, :config_description, [
group: :pleroma_job_queue,
key: :queues,
type: :group,
- description: "[Deprecated] Replaced with `Oban`/`:queues` (keeping the same format)",
- children: []
+ description: "[Deprecated] Replaced with `Oban`/`:queues` (keeping the same format)"
},
%{
group: :pleroma,
@@ -1790,8 +1674,7 @@ config :pleroma, :config_description, [
%{
key: :max_retries,
type: :integer,
- description: "[Deprecated] Replaced as `Oban`/`:queues`/`:outgoing_federation` value",
- suggestions: []
+ description: "[Deprecated] Replaced as `Oban`/`:queues`/`:outgoing_federation` value"
}
]
},
@@ -1817,8 +1700,7 @@ config :pleroma, :config_description, [
%{
key: :verbose,
type: :boolean,
- description: "Logs verbose mode",
- suggestions: [false, true]
+ description: "Logs verbose mode"
},
%{
key: :prune,
@@ -1937,11 +1819,7 @@ config :pleroma, :config_description, [
%{
key: :unfurl_nsfw,
type: :boolean,
- description: "If set to true nsfw attachments will be shown in previews",
- suggestions: [
- true,
- false
- ]
+ description: "If set to true nsfw attachments will be shown in previews"
}
]
},
@@ -1949,14 +1827,12 @@ config :pleroma, :config_description, [
group: :pleroma,
key: :rich_media,
type: :group,
- description: "",
children: [
%{
key: :enabled,
type: :boolean,
description:
- "if enabled the instance will parse metadata from attached links to generate link previews",
- suggestions: [true, false]
+ "if enabled the instance will parse metadata from attached links to generate link previews"
},
%{
key: :ignore_hosts,
@@ -1998,8 +1874,7 @@ config :pleroma, :config_description, [
key: :enabled,
type: :boolean,
description:
- "if enabled, when a new user is federated with, fetch some of their latest posts",
- suggestions: [true, false]
+ "if enabled, when a new user is federated with, fetch some of their latest posts"
},
%{
key: :pages,
@@ -2030,14 +1905,12 @@ config :pleroma, :config_description, [
%{
key: :new_window,
type: :boolean,
- description: "set to false to remove target='_blank' attribute",
- suggestions: [true, false]
+ description: "set to false to remove target='_blank' attribute"
},
%{
key: :scheme,
type: :boolean,
- description: "Set to true to link urls with schema http://google.com",
- suggestions: [true, false]
+ description: "Set to true to link urls with schema http://google.com"
},
%{
key: :truncate,
@@ -2049,14 +1922,12 @@ config :pleroma, :config_description, [
%{
key: :strip_prefix,
type: :boolean,
- description: "Strip the scheme prefix",
- suggestions: [true, false]
+ description: "Strip the scheme prefix"
},
%{
key: :extra,
type: :boolean,
- description: "link urls with rarely used schemes (magnet, ipfs, irc, etc.)",
- suggestions: [true, false]
+ description: "link urls with rarely used schemes (magnet, ipfs, irc, etc.)"
}
]
},
@@ -2083,8 +1954,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "whether scheduled activities are sent to the job queue to be executed",
- suggestions: [true, false]
+ description: "whether scheduled activities are sent to the job queue to be executed"
}
]
},
@@ -2097,8 +1967,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "whether expired activities will be sent to the job queue to be deleted",
- suggestions: [true, false]
+ description: "whether expired activities will be sent to the job queue to be deleted"
}
]
},
@@ -2110,7 +1979,6 @@ config :pleroma, :config_description, [
%{
key: Pleroma.Web.Auth.Authenticator,
type: :module,
- description: "",
suggestions: [Pleroma.Web.Auth.PleromaAuthenticator, Pleroma.Web.Auth.LDAPAuthenticator]
}
]
@@ -2128,8 +1996,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "enables LDAP authentication",
- suggestions: [true, false]
+ description: "enables LDAP authentication"
},
%{
key: :host,
@@ -2146,26 +2013,22 @@ config :pleroma, :config_description, [
%{
key: :ssl,
type: :boolean,
- description: "true to use SSL, usually implies the port 636",
- suggestions: [true, false]
+ description: "true to use SSL, usually implies the port 636"
},
%{
key: :sslopts,
type: :keyword,
- description: "additional SSL options",
- suggestions: []
+ description: "additional SSL options"
},
%{
key: :tls,
type: :boolean,
- description: "true to start TLS, usually implies the port 389",
- suggestions: [true, false]
+ description: "true to start TLS, usually implies the port 389"
},
%{
key: :tlsopts,
type: :keyword,
- description: "additional TLS options",
- suggestions: []
+ description: "additional TLS options"
},
%{
key: :base,
@@ -2237,8 +2100,7 @@ config :pleroma, :config_description, [
%{
key: :active,
type: :boolean,
- description: "globally enable or disable digest emails",
- suggestions: [true, false]
+ description: "globally enable or disable digest emails"
},
%{
key: :schedule,
@@ -2271,7 +2133,7 @@ config :pleroma, :config_description, [
children: [
%{
key: :logo,
- # type: [:string, nil],
+ type: [:string, nil],
description: "a path to a custom logo. Set it to nil to use the default Pleroma logo",
suggestions: ["some/path/logo.png", nil]
},
@@ -2293,37 +2155,31 @@ config :pleroma, :config_description, [
%{
key: :link_color,
type: :string,
- description: "",
suggestions: ["#d8a070"]
},
%{
key: :background_color,
type: :string,
- description: "",
suggestions: ["#2C3645"]
},
%{
key: :content_background_color,
type: :string,
- description: "",
suggestions: ["#1B2635"]
},
%{
key: :header_color,
type: :string,
- description: "",
suggestions: ["#d8a070"]
},
%{
key: :text_color,
type: :string,
- description: "",
suggestions: ["#b9b9ba"]
},
%{
key: :text_muted_color,
type: :string,
- description: "",
suggestions: ["#b9b9ba"]
}
]
@@ -2346,14 +2202,12 @@ config :pleroma, :config_description, [
key: :issue_new_refresh_token,
type: :boolean,
description:
- "Keeps old refresh token or generate new refresh token when to obtain an access token",
- suggestions: [true, false]
+ "Keeps old refresh token or generate new refresh token when to obtain an access token"
},
%{
key: :clean_expired_tokens,
type: :boolean,
- description: "Enable a background job to clean expired oauth tokens. Defaults to false",
- suggestions: [true, false]
+ description: "Enable a background job to clean expired oauth tokens. Defaults to false"
},
%{
key: :clean_expired_tokens_interval,
@@ -2368,7 +2222,6 @@ config :pleroma, :config_description, [
group: :pleroma,
key: :emoji,
type: :group,
- description: "",
children: [
%{
key: :shortcode_globs,
@@ -2415,8 +2268,7 @@ config :pleroma, :config_description, [
%{
key: :rum_enabled,
type: :boolean,
- description: "If RUM indexes should be used. Defaults to false",
- suggestions: [true, false]
+ description: "If RUM indexes should be used. Defaults to false"
}
]
},
@@ -2475,8 +2327,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Enables ssh",
- suggestions: [true, false]
+ description: "Enables ssh"
},
%{
key: :priv_dir,
@@ -2512,7 +2363,6 @@ config :pleroma, :config_description, [
%{
key: :types,
type: :map,
- description: "",
suggestions: [
%{
"application/xml" => ["xml"],
@@ -2526,31 +2376,26 @@ config :pleroma, :config_description, [
%{
key: "application/xml",
type: {:list, :string},
- description: "",
suggestions: [["xml"]]
},
%{
key: "application/xrd+xml",
type: {:list, :string},
- description: "",
suggestions: [["xrd+xml"]]
},
%{
key: "application/jrd+json",
type: {:list, :string},
- description: "",
suggestions: [["jrd+json"]]
},
%{
key: "application/activity+json",
type: {:list, :string},
- description: "",
suggestions: [["activity+json"]]
},
%{
key: "application/ld+json",
type: {:list, :string},
- description: "",
suggestions: [["activity+json"]]
}
]
@@ -2578,9 +2423,7 @@ config :pleroma, :config_description, [
children: [
%{
key: :enabled,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
}
]
},
@@ -2588,13 +2431,11 @@ config :pleroma, :config_description, [
group: :pleroma,
key: :suggestions,
type: :group,
- description: "",
children: [
%{
key: :enabled,
type: :boolean,
- description: "Enables suggestions",
- suggestions: []
+ description: "Enables suggestions"
},
%{
key: :third_party_engine,
@@ -2619,7 +2460,6 @@ config :pleroma, :config_description, [
%{
key: :web,
type: :string,
- description: "",
suggestions: ["https://vinayaka.distsn.org"]
}
]
@@ -2646,7 +2486,6 @@ config :pleroma, :config_description, [
%{
key: :adapter,
type: :module,
- description: "",
suggestions: [Pleroma.Signature]
}
]
@@ -2655,18 +2494,15 @@ config :pleroma, :config_description, [
group: :pleroma,
key: Pleroma.Uploaders.MDII,
type: :group,
- description: "",
children: [
%{
key: :cgi,
type: :string,
- description: "",
suggestions: ["https://mdii.sakura.ne.jp/mdii-post.cgi"]
},
%{
key: :files,
type: :string,
- description: "",
suggestions: ["https://mdii.sakura.ne.jp"]
}
]
@@ -2680,19 +2516,15 @@ config :pleroma, :config_description, [
%{
key: :proxy_url,
type: [:string, :atom, nil],
- description: "",
suggestions: ["localhost:9020", {:socks5, :localhost, 3090}, nil]
},
%{
key: :send_user_agent,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
},
%{
key: :adapter,
type: :keyword,
- description: "",
suggestions: [
[
ssl_options: [
@@ -2710,36 +2542,26 @@ config :pleroma, :config_description, [
group: :pleroma,
key: :markup,
type: :group,
- description: "",
children: [
%{
key: :allow_inline_images,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
},
%{
key: :allow_headings,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
},
%{
key: :allow_tables,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
},
%{
key: :allow_fonts,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
},
%{
key: :scrub_policy,
type: {:list, :module},
- description: "",
suggestions: [[Pleroma.HTML.Transform.MediaProxy, Pleroma.HTML.Scrubber.Default]]
}
]
@@ -2748,13 +2570,10 @@ config :pleroma, :config_description, [
group: :pleroma,
key: :user,
type: :group,
- description: "",
children: [
%{
key: :deny_follow_blocked,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
}
]
},
@@ -2762,12 +2581,10 @@ config :pleroma, :config_description, [
group: :pleroma,
key: :mrf_normalize_markup,
type: :group,
- description: "",
children: [
%{
key: :scrub_policy,
type: :module,
- description: "",
suggestions: [Pleroma.HTML.Scrubber.Default]
}
]
@@ -2776,12 +2593,10 @@ config :pleroma, :config_description, [
group: :pleroma,
key: Pleroma.User,
type: :group,
- description: "",
children: [
%{
key: :restricted_nicknames,
type: {:list, :string},
- description: "",
suggestions: [
[
".well-known",
@@ -2822,24 +2637,20 @@ config :pleroma, :config_description, [
%{
group: :cors_plug,
type: :group,
- description: "",
children: [
%{
key: :max_age,
type: :integer,
- description: "",
suggestions: [86_400]
},
%{
key: :methods,
type: {:list, :string},
- description: "",
suggestions: [["POST", "PUT", "DELETE", "GET", "PATCH", "OPTIONS"]]
},
%{
key: :expose,
type: :string,
- description: "",
suggestions: [
[
"Link",
@@ -2853,14 +2664,11 @@ config :pleroma, :config_description, [
},
%{
key: :credentials,
- type: :boolean,
- description: "",
- suggestions: [true, false]
+ type: :boolean
},
%{
key: :headers,
type: {:list, :string},
- description: "",
suggestions: [["Authorization", "Content-Type", "Idempotency-Key"]]
}
]
diff --git a/docs/api/admin_api.md b/docs/api/admin_api.md
index 9362e3d78..7637fa0d4 100644
--- a/docs/api/admin_api.md
+++ b/docs/api/admin_api.md
@@ -224,15 +224,25 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
## `/api/pleroma/admin/users/invite_token`
-### Get an account registration invite token
+### Create an account registration invite token
-- Methods: `GET`
+- Methods: `POST`
- Params:
- - *optional* `invite` => [
- - *optional* `max_use` (integer)
- - *optional* `expires_at` (date string e.g. "2019-04-07")
- ]
-- Response: invite token (base64 string)
+ - *optional* `max_use` (integer)
+ - *optional* `expires_at` (date string e.g. "2019-04-07")
+- Response:
+
+```json
+{
+ "id": integer,
+ "token": string,
+ "used": boolean,
+ "expires_at": date,
+ "uses": integer,
+ "max_use": integer,
+ "invite_type": string (possible values: `one_time`, `reusable`, `date_limited`, `reusable_date_limited`)
+}
+```
## `/api/pleroma/admin/users/invites`
diff --git a/docs/api/differences_in_mastoapi_responses.md b/docs/api/differences_in_mastoapi_responses.md
index 9b32baf3a..3c7f5dad7 100644
--- a/docs/api/differences_in_mastoapi_responses.md
+++ b/docs/api/differences_in_mastoapi_responses.md
@@ -50,6 +50,8 @@ Has these additional fields under the `pleroma` object:
- `confirmation_pending`: boolean, true if a new user account is waiting on email confirmation to be activated
- `hide_followers`: boolean, true when the user has follower hiding enabled
- `hide_follows`: boolean, true when the user has follow hiding enabled
+- `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 `verify_credentials` and `update_credentials`
- `chat_token`: The token needed for Pleroma chat. Only returned in `verify_credentials`
- `deactivated`: boolean, true when the user is deactivated
@@ -112,6 +114,8 @@ Additional parameters can be added to the JSON body/Form data:
- `no_rich_text` - if true, html tags are stripped from all statuses requested from the API
- `hide_followers` - if true, user's followers will be hidden
- `hide_follows` - if true, user's follows will be hidden
+- `hide_followers_count` - if true, user's follower count will be hidden
+- `hide_follows_count` - if true, user's follow count will be hidden
- `hide_favorites` - if true, user's favorites timeline will be hidden
- `show_role` - if true, user's role (e.g admin, moderator) will be exposed to anyone in the API
- `default_scope` - the scope returned under `privacy` key in Source subentity
diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex
index ef1418543..0bf20cdd0 100644
--- a/lib/pleroma/constants.ex
+++ b/lib/pleroma/constants.ex
@@ -6,4 +6,16 @@ defmodule Pleroma.Constants do
use Const
const(as_public, do: "https://www.w3.org/ns/activitystreams#Public")
+
+ const(object_internal_fields,
+ do: [
+ "likes",
+ "like_count",
+ "announcements",
+ "announcement_count",
+ "emoji",
+ "context_id",
+ "deleted_activity_id"
+ ]
+ )
end
diff --git a/lib/pleroma/docs/markdown.ex b/lib/pleroma/docs/markdown.ex
index 8386dc2fb..68b106499 100644
--- a/lib/pleroma/docs/markdown.ex
+++ b/lib/pleroma/docs/markdown.ex
@@ -23,7 +23,7 @@ defmodule Pleroma.Docs.Markdown do
IO.write(file, "#{group[:description]}\n")
- for child <- group[:children] do
+ for child <- group[:children] || [] do
print_child_header(file, child)
print_suggestions(file, child[:suggestions])
@@ -44,6 +44,17 @@ defmodule Pleroma.Docs.Markdown do
{:ok, config_path}
end
+ defp print_child_header(file, %{key: key, type: type, description: description} = _child) do
+ IO.write(
+ file,
+ "- `#{inspect(key)}` (`#{inspect(type)}`): #{description} \n"
+ )
+ end
+
+ defp print_child_header(file, %{key: key, type: type} = _child) do
+ IO.write(file, "- `#{inspect(key)}` (`#{inspect(type)}`) \n")
+ end
+
defp print_suggestion(file, suggestion) when is_list(suggestion) do
IO.write(file, " `#{inspect(suggestion)}`\n")
end
@@ -59,20 +70,19 @@ defmodule Pleroma.Docs.Markdown do
defp print_suggestions(_file, nil), do: nil
- defp print_suggestions(file, suggestions) do
- IO.write(file, "Suggestions:\n")
+ defp print_suggestions(_file, ""), do: nil
+ defp print_suggestions(file, suggestions) do
if length(suggestions) > 1 do
+ IO.write(file, "Suggestions:\n")
+
for suggestion <- suggestions do
print_suggestion(file, suggestion, true)
end
else
+ IO.write(file, " Suggestion: ")
+
print_suggestion(file, List.first(suggestions))
end
end
-
- defp print_child_header(file, child) do
- IO.write(file, "- `#{inspect(child[:key])}` -`#{inspect(child[:type])}` \n")
- IO.write(file, "#{child[:description]} \n")
- end
end
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
index 5033798ae..3fa407931 100644
--- a/lib/pleroma/object.ex
+++ b/lib/pleroma/object.ex
@@ -38,6 +38,24 @@ defmodule Pleroma.Object do
def get_by_id(nil), do: nil
def get_by_id(id), do: Repo.get(Object, id)
+ def get_by_id_and_maybe_refetch(id, opts \\ []) do
+ %{updated_at: updated_at} = object = get_by_id(id)
+
+ if opts[:interval] &&
+ NaiveDateTime.diff(NaiveDateTime.utc_now(), updated_at) > opts[:interval] do
+ case Fetcher.refetch_object(object) do
+ {:ok, %Object{} = object} ->
+ object
+
+ e ->
+ Logger.error("Couldn't refresh #{object.data["id"]}:\n#{inspect(e)}")
+ object
+ end
+ else
+ object
+ end
+ end
+
def get_by_ap_id(nil), do: nil
def get_by_ap_id(ap_id) do
diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex
index c1795ae0f..cea33b5af 100644
--- a/lib/pleroma/object/fetcher.ex
+++ b/lib/pleroma/object/fetcher.ex
@@ -6,18 +6,39 @@ defmodule Pleroma.Object.Fetcher do
alias Pleroma.HTTP
alias Pleroma.Object
alias Pleroma.Object.Containment
+ alias Pleroma.Repo
alias Pleroma.Signature
alias Pleroma.Web.ActivityPub.InternalFetchActor
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.OStatus
require Logger
+ require Pleroma.Constants
- defp reinject_object(data) do
+ defp touch_changeset(changeset) do
+ updated_at =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.truncate(:second)
+
+ Ecto.Changeset.put_change(changeset, :updated_at, updated_at)
+ end
+
+ defp maybe_reinject_internal_fields(data, %{data: %{} = old_data}) do
+ internal_fields = Map.take(old_data, Pleroma.Constants.object_internal_fields())
+
+ Map.merge(data, internal_fields)
+ end
+
+ defp maybe_reinject_internal_fields(data, _), do: data
+
+ defp reinject_object(struct, data) do
Logger.debug("Reinjecting object #{data["id"]}")
with data <- Transmogrifier.fix_object(data),
- {:ok, object} <- Object.create(data) do
+ data <- maybe_reinject_internal_fields(data, struct),
+ changeset <- Object.change(struct, %{data: data}),
+ changeset <- touch_changeset(changeset),
+ {:ok, object} <- Repo.insert_or_update(changeset) do
{:ok, object}
else
e ->
@@ -26,6 +47,17 @@ defmodule Pleroma.Object.Fetcher do
end
end
+ def refetch_object(%Object{data: %{"id" => id}} = object) do
+ with {:local, false} <- {:local, String.starts_with?(id, Pleroma.Web.base_url() <> "/")},
+ {:ok, data} <- fetch_and_contain_remote_object_from_id(id),
+ {:ok, object} <- reinject_object(object, data) do
+ {:ok, object}
+ else
+ {:local, true} -> object
+ e -> {:error, e}
+ end
+ end
+
# TODO:
# This will create a Create activity, which we need internally at the moment.
def fetch_object_from_id(id, options \\ []) do
@@ -57,7 +89,7 @@ defmodule Pleroma.Object.Fetcher do
{:reject, nil}
{:object, data, nil} ->
- reinject_object(data)
+ reinject_object(%Object{}, data)
{:normalize, object = %Object{}} ->
{:ok, object}
diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex
index 151e025de..b150a57cd 100644
--- a/lib/pleroma/user/info.ex
+++ b/lib/pleroma/user/info.ex
@@ -41,6 +41,8 @@ defmodule Pleroma.User.Info do
field(:topic, :string, default: nil)
field(:hub, :string, default: nil)
field(:salmon, :string, default: nil)
+ field(:hide_followers_count, :boolean, default: false)
+ field(:hide_follows_count, :boolean, default: false)
field(:hide_followers, :boolean, default: false)
field(:hide_follows, :boolean, default: false)
field(:hide_favorites, :boolean, default: true)
@@ -262,6 +264,8 @@ defmodule Pleroma.User.Info do
:salmon,
:hide_followers,
:hide_follows,
+ :hide_followers_count,
+ :hide_follows_count,
:follower_count,
:fields,
:following_count
@@ -281,7 +285,9 @@ defmodule Pleroma.User.Info do
:following_count,
:hide_follows,
:fields,
- :hide_followers
+ :hide_followers,
+ :hide_followers_count,
+ :hide_follows_count
])
|> validate_fields(remote?)
end
@@ -295,6 +301,8 @@ defmodule Pleroma.User.Info do
:banner,
:hide_follows,
:hide_followers,
+ :hide_followers_count,
+ :hide_follows_count,
:hide_favorites,
:background,
:show_role,
@@ -458,7 +466,9 @@ defmodule Pleroma.User.Info do
:hide_followers,
:hide_follows,
:follower_count,
- :following_count
+ :following_count,
+ :hide_followers_count,
+ :hide_follows_count
])
end
end
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 8461b666e..9d2ddc1cd 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -979,15 +979,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
defp strip_internal_fields(object) do
object
- |> Map.drop([
- "likes",
- "like_count",
- "announcements",
- "announcement_count",
- "emoji",
- "context_id",
- "deleted_activity_id"
- ])
+ |> Map.drop(Pleroma.Constants.object_internal_fields())
end
defp strip_internal_tags(%{"tag" => tags} = object) do
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 7be734b26..164b973d0 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -118,30 +118,34 @@ defmodule Pleroma.Web.ActivityPub.UserView do
end
def render("following.json", %{user: user, page: page} = opts) do
- showing = (opts[:for] && opts[:for] == user) || !user.info.hide_follows
+ showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_follows
+ showing_count = showing_items || !user.info.hide_follows_count
+
query = User.get_friends_query(user)
query = from(user in query, select: [:ap_id])
following = Repo.all(query)
total =
- if showing do
+ if showing_count do
length(following)
else
0
end
- collection(following, "#{user.ap_id}/following", page, showing, total)
+ collection(following, "#{user.ap_id}/following", page, showing_items, total)
|> Map.merge(Utils.make_json_ld_header())
end
def render("following.json", %{user: user} = opts) do
- showing = (opts[:for] && opts[:for] == user) || !user.info.hide_follows
+ showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_follows
+ showing_count = showing_items || !user.info.hide_follows_count
+
query = User.get_friends_query(user)
query = from(user in query, select: [:ap_id])
following = Repo.all(query)
total =
- if showing do
+ if showing_count do
length(following)
else
0
@@ -152,7 +156,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"type" => "OrderedCollection",
"totalItems" => total,
"first" =>
- if showing do
+ if showing_items do
collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows)
else
"#{user.ap_id}/following?page=1"
@@ -162,32 +166,34 @@ defmodule Pleroma.Web.ActivityPub.UserView do
end
def render("followers.json", %{user: user, page: page} = opts) do
- showing = (opts[:for] && opts[:for] == user) || !user.info.hide_followers
+ showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_followers
+ showing_count = showing_items || !user.info.hide_followers_count
query = User.get_followers_query(user)
query = from(user in query, select: [:ap_id])
followers = Repo.all(query)
total =
- if showing do
+ if showing_count do
length(followers)
else
0
end
- collection(followers, "#{user.ap_id}/followers", page, showing, total)
+ collection(followers, "#{user.ap_id}/followers", page, showing_items, total)
|> Map.merge(Utils.make_json_ld_header())
end
def render("followers.json", %{user: user} = opts) do
- showing = (opts[:for] && opts[:for] == user) || !user.info.hide_followers
+ showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_followers
+ showing_count = showing_items || !user.info.hide_followers_count
query = User.get_followers_query(user)
query = from(user in query, select: [:ap_id])
followers = Repo.all(query)
total =
- if showing do
+ if showing_count do
length(followers)
else
0
@@ -198,8 +204,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"type" => "OrderedCollection",
"totalItems" => total,
"first" =>
- if showing do
- collection(followers, "#{user.ap_id}/followers", 1, showing, total)
+ if showing_items do
+ collection(followers, "#{user.ap_id}/followers", 1, showing_items, total)
else
"#{user.ap_id}/followers?page=1"
end
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index 2a1cc59e5..8a8091daa 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -400,13 +400,23 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
end
end
- @doc "Get a account registeration invite token (base64 string)"
- def get_invite_token(conn, params) do
- options = params["invite"] || %{}
- {:ok, invite} = UserInviteToken.create_invite(options)
+ @doc "Create an account registration invite token"
+ def create_invite_token(conn, params) do
+ opts = %{}
- conn
- |> json(invite.token)
+ opts =
+ if params["max_use"],
+ do: Map.put(opts, :max_use, params["max_use"]),
+ else: opts
+
+ opts =
+ if params["expires_at"],
+ do: Map.put(opts, :expires_at, params["expires_at"]),
+ else: opts
+
+ {:ok, invite} = UserInviteToken.create_invite(opts)
+
+ json(conn, AccountView.render("invite.json", %{invite: invite}))
end
@doc "Get list of created invites"
diff --git a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
index 060137b80..37eeb2ac3 100644
--- a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
@@ -147,6 +147,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
[
:no_rich_text,
:locked,
+ :hide_followers_count,
+ :hide_follows_count,
:hide_followers,
:hide_follows,
:hide_favorites,
@@ -485,7 +487,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def get_poll(%{assigns: %{user: user}} = conn, %{"id" => id}) do
- with %Object{} = object <- Object.get_by_id(id),
+ with %Object{} = object <- Object.get_by_id_and_maybe_refetch(id, interval: 60),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]),
true <- Visibility.visible_for_user?(activity, user) do
conn
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 169116d0d..195dd124b 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -74,10 +74,18 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
user_info = User.get_cached_user_info(user)
following_count =
- ((!user.info.hide_follows or opts[:for] == user) && user_info.following_count) || 0
+ if !user.info.hide_follows_count or !user.info.hide_follows or opts[:for] == user do
+ user_info.following_count
+ else
+ 0
+ end
followers_count =
- ((!user.info.hide_followers or opts[:for] == user) && user_info.follower_count) || 0
+ if !user.info.hide_followers_count or !user.info.hide_followers or opts[:for] == user do
+ user_info.follower_count
+ else
+ 0
+ end
bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"]
@@ -138,6 +146,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
pleroma: %{
confirmation_pending: user_info.confirmation_pending,
tags: user.tags,
+ hide_followers_count: user.info.hide_followers_count,
+ hide_follows_count: user.info.hide_follows_count,
hide_followers: user.info.hide_followers,
hide_follows: user.info.hide_follows,
hide_favorites: user.info.hide_favorites,
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 401133bf3..b9b85fd67 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -180,7 +180,7 @@ defmodule Pleroma.Web.Router do
post("/relay", AdminAPIController, :relay_follow)
delete("/relay", AdminAPIController, :relay_unfollow)
- get("/users/invite_token", AdminAPIController, :get_invite_token)
+ post("/users/invite_token", AdminAPIController, :create_invite_token)
get("/users/invites", AdminAPIController, :invites)
post("/users/revoke_invite", AdminAPIController, :revoke_invite)
post("/users/email_invite", AdminAPIController, :email_invite)
diff --git a/mix.exs b/mix.exs
index 58d1606d3..f2635da24 100644
--- a/mix.exs
+++ b/mix.exs
@@ -5,7 +5,7 @@ defmodule Pleroma.Mixfile do
[
app: :pleroma,
version: version("1.0.0"),
- elixir: "~> 1.7",
+ elixir: "~> 1.8",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
elixirc_options: [warnings_as_errors: true],
@@ -113,7 +113,7 @@ defmodule Pleroma.Mixfile do
{:calendar, "~> 0.17.4"},
{:cachex, "~> 3.0.2"},
{:poison, "~> 3.0", override: true},
- {:tesla, "~> 1.2"},
+ {:tesla, "~> 1.3", override: true},
{:jason, "~> 1.0"},
{:mogrify, "~> 0.6.1"},
{:ex_aws, "~> 2.1"},
@@ -174,7 +174,8 @@ defmodule Pleroma.Mixfile do
"ecto.rollback": ["pleroma.ecto.rollback"],
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
- test: ["ecto.create --quiet", "ecto.migrate", "test"]
+ test: ["ecto.create --quiet", "ecto.migrate", "test"],
+ docs: ["pleroma.docs", "docs"]
]
end
diff --git a/mix.lock b/mix.lock
index 547ff6be6..24b34c09c 100644
--- a/mix.lock
+++ b/mix.lock
@@ -90,7 +90,7 @@
"swoosh": {:hex, :swoosh, "0.23.2", "7dda95ff0bf54a2298328d6899c74dae1223777b43563ccebebb4b5d2b61df38", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"},
"syslog": {:git, "https://github.com/Vagabond/erlang-syslog.git", "4a6c6f2c996483e86c1320e9553f91d337bcb6aa", [tag: "1.0.5"]},
"telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm"},
- "tesla": {:hex, :tesla, "1.2.1", "864783cc27f71dd8c8969163704752476cec0f3a51eb3b06393b3971dc9733ff", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
+ "tesla": {:hex, :tesla, "1.3.0", "f35d72f029e608f9cdc6f6d6fcc7c66cf6d6512a70cfef9206b21b8bd0203a30", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 0.4", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
"timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"tzdata": {:hex, :tzdata, "0.5.21", "8cbf3607fcce69636c672d5be2bbb08687fe26639a62bdcc283d267277db7cf0", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
diff --git a/test/fixtures/tesla_mock/poll_modified.json b/test/fixtures/tesla_mock/poll_modified.json
new file mode 100644
index 000000000..1d026b592
--- /dev/null
+++ b/test/fixtures/tesla_mock/poll_modified.json
@@ -0,0 +1 @@
+{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://patch.cx/users/rin","attachment":[],"attributedTo":"https://patch.cx/users/rin","cc":["https://patch.cx/users/rin/followers"],"closed":"2019-09-19T00:32:36.785333","content":"can you vote on this poll?","context":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","conversation":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","id":"https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d","oneOf":[{"name":"yes","replies":{"totalItems":8,"type":"Collection"},"type":"Note"},{"name":"no","replies":{"totalItems":3,"type":"Collection"},"type":"Note"}],"published":"2019-09-18T14:32:36.802152Z","sensitive":false,"summary":"","tag":[],"to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Question"} \ No newline at end of file
diff --git a/test/fixtures/tesla_mock/poll_original.json b/test/fixtures/tesla_mock/poll_original.json
new file mode 100644
index 000000000..267876b3c
--- /dev/null
+++ b/test/fixtures/tesla_mock/poll_original.json
@@ -0,0 +1 @@
+{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://patch.cx/users/rin","attachment":[],"attributedTo":"https://patch.cx/users/rin","cc":["https://patch.cx/users/rin/followers"],"closed":"2019-09-19T00:32:36.785333","content":"can you vote on this poll?","context":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","conversation":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","id":"https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d","oneOf":[{"name":"yes","replies":{"totalItems":4,"type":"Collection"},"type":"Note"},{"name":"no","replies":{"totalItems":0,"type":"Collection"},"type":"Note"}],"published":"2019-09-18T14:32:36.802152Z","sensitive":false,"summary":"","tag":[],"to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Question"} \ No newline at end of file
diff --git a/test/fixtures/tesla_mock/rin.json b/test/fixtures/tesla_mock/rin.json
new file mode 100644
index 000000000..2cf623764
--- /dev/null
+++ b/test/fixtures/tesla_mock/rin.json
@@ -0,0 +1 @@
+{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"attachment":[],"endpoints":{"oauthAuthorizationEndpoint":"https://patch.cx/oauth/authorize","oauthRegistrationEndpoint":"https://patch.cx/api/v1/apps","oauthTokenEndpoint":"https://patch.cx/oauth/token","sharedInbox":"https://patch.cx/inbox"},"followers":"https://patch.cx/users/rin/followers","following":"https://patch.cx/users/rin/following","icon":{"type":"Image","url":"https://patch.cx/media/4e914f5b84e4a259a3f6c2d2edc9ab642f2ab05f3e3d9c52c81fc2d984b3d51e.jpg"},"id":"https://patch.cx/users/rin","image":{"type":"Image","url":"https://patch.cx/media/f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg?name=f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg"},"inbox":"https://patch.cx/users/rin/inbox","manuallyApprovesFollowers":false,"name":"rinpatch","outbox":"https://patch.cx/users/rin/outbox","preferredUsername":"rin","publicKey":{"id":"https://patch.cx/users/rin#main-key","owner":"https://patch.cx/users/rin","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5DLtwGXNZElJyxFGfcVc\nXANhaMadj/iYYQwZjOJTV9QsbtiNBeIK54PJrYuU0/0YIdrvS1iqheX5IwXRhcwa\nhm3ZyLz7XeN9st7FBni4BmZMBtMpxAuYuu5p/jbWy13qAiYOhPreCx0wrWgm/lBD\n9mkgaxIxPooBE0S4ZWEJIDIV1Vft3AWcRUyWW1vIBK0uZzs6GYshbQZB952S0yo4\nFzI1hABGHncH8UvuFauh4EZ8tY7/X5I0pGRnDOcRN1dAht5w5yTA+6r5kebiFQjP\nIzN/eCO/a9Flrj9YGW7HDNtjSOH0A31PLRGlJtJO3yK57dnf5ppyCZGfL4emShQo\ncQIDAQAB\n-----END PUBLIC KEY-----\n\n"},"summary":"your friendly neighborhood pleroma developer<br>I like cute things and distributed systems, and really hate delete and redrafts","tag":[],"type":"Person","url":"https://patch.cx/users/rin"} \ No newline at end of file
diff --git a/test/object_test.exs b/test/object_test.exs
index 570213a61..dd228c32f 100644
--- a/test/object_test.exs
+++ b/test/object_test.exs
@@ -4,10 +4,13 @@
defmodule Pleroma.ObjectTest do
use Pleroma.DataCase
+ import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
+ alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Repo
+ alias Pleroma.Web.CommonAPI
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
@@ -89,4 +92,110 @@ defmodule Pleroma.ObjectTest do
)
end
end
+
+ describe "get_by_id_and_maybe_refetch" do
+ setup do
+ mock(fn
+ %{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} ->
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/poll_original.json")}
+
+ env ->
+ apply(HttpRequestMock, :request, [env])
+ end)
+
+ mock_modified = fn resp ->
+ mock(fn
+ %{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} ->
+ resp
+
+ env ->
+ apply(HttpRequestMock, :request, [env])
+ end)
+ end
+
+ on_exit(fn -> mock(fn env -> apply(HttpRequestMock, :request, [env]) end) end)
+
+ [mock_modified: mock_modified]
+ end
+
+ test "refetches if the time since the last refetch is greater than the interval", %{
+ mock_modified: mock_modified
+ } do
+ %Object{} =
+ object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+
+ assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
+ assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
+
+ mock_modified.(%Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
+ })
+
+ updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
+ assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8
+ assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3
+ end
+
+ test "returns the old object if refetch fails", %{mock_modified: mock_modified} do
+ %Object{} =
+ object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+
+ assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
+ assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
+
+ assert capture_log(fn ->
+ mock_modified.(%Tesla.Env{status: 404, body: ""})
+
+ updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
+ assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4
+ assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0
+ end) =~
+ "[error] Couldn't refresh https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"
+ end
+
+ test "does not refetch if the time since the last refetch is greater than the interval", %{
+ mock_modified: mock_modified
+ } do
+ %Object{} =
+ object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+
+ assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
+ assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
+
+ mock_modified.(%Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
+ })
+
+ updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: 100)
+ assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4
+ assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0
+ end
+
+ test "preserves internal fields on refetch", %{mock_modified: mock_modified} do
+ %Object{} =
+ object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+
+ assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
+ assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
+
+ user = insert(:user)
+ activity = Activity.get_create_by_object_ap_id(object.data["id"])
+ {:ok, _activity, object} = CommonAPI.favorite(activity.id, user)
+
+ assert object.data["like_count"] == 1
+
+ mock_modified.(%Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
+ })
+
+ updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
+ assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8
+ assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3
+
+ assert updated_object.data["like_count"] == 1
+ end
+ end
end
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index 6f9886836..5506c0626 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -1004,6 +1004,10 @@ defmodule HttpRequestMock do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}}
end
+ def get("https://patch.cx/users/rin", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/rin.json")}}
+ end
+
def get(url, query, body, headers) do
{:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
diff --git a/test/test_helper.exs b/test/test_helper.exs
index fb33e0969..c8dbee010 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -7,3 +7,8 @@ ExUnit.start(exclude: os_exclude)
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual)
Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client)
{:ok, _} = Application.ensure_all_started(:ex_machina)
+
+ExUnit.after_suite(fn _results ->
+ uploads = Pleroma.Config.get([Pleroma.Uploaders.Local, :uploads], "test/uploads")
+ File.rm_rf!(uploads)
+end)
diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs
index fb7fd9e79..2b4a04afd 100644
--- a/test/web/activity_pub/views/user_view_test.exs
+++ b/test/web/activity_pub/views/user_view_test.exs
@@ -105,10 +105,20 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
other_user = insert(:user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
- info = Map.put(user.info, :hide_followers, true)
+ info = Map.merge(user.info, %{hide_followers_count: true, hide_followers: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user})
end
+
+ test "sets correct totalItems when followers are hidden but the follower counter is not" do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
+ info = Map.merge(user.info, %{hide_followers_count: false, hide_followers: true})
+ user = Map.put(user, :info, info)
+ assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
+ end
end
describe "following" do
@@ -117,9 +127,19 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
other_user = insert(:user)
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
- info = Map.put(user.info, :hide_follows, true)
+ info = Map.merge(user.info, %{hide_follows_count: true, hide_follows: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user})
end
+
+ test "sets correct totalItems when follows are hidden but the follow counter is not" do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
+ assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
+ info = Map.merge(user.info, %{hide_follows_count: false, hide_follows: true})
+ user = Map.put(user, :info, info)
+ assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
+ end
end
end
diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs
index 41b4364f2..108143f6a 100644
--- a/test/web/admin_api/admin_api_controller_test.exs
+++ b/test/web/admin_api/admin_api_controller_test.exs
@@ -574,18 +574,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
- test "/api/pleroma/admin/users/invite_token" do
- admin = insert(:user, info: %{is_admin: true})
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> put_req_header("accept", "application/json")
- |> get("/api/pleroma/admin/users/invite_token")
-
- assert conn.status == 200
- end
-
test "/api/pleroma/admin/users/:nickname/password_reset" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
@@ -1064,7 +1052,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"@#{admin.nickname} deactivated user @#{user.nickname}"
end
- describe "GET /api/pleroma/admin/users/invite_token" do
+ describe "POST /api/pleroma/admin/users/invite_token" do
setup do
admin = insert(:user, info: %{is_admin: true})
@@ -1076,10 +1064,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
test "without options", %{conn: conn} do
- conn = get(conn, "/api/pleroma/admin/users/invite_token")
+ conn = post(conn, "/api/pleroma/admin/users/invite_token")
- token = json_response(conn, 200)
- invite = UserInviteToken.find_by_token!(token)
+ invite_json = json_response(conn, 200)
+ invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
refute invite.expires_at
refute invite.max_use
@@ -1088,12 +1076,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
test "with expires_at", %{conn: conn} do
conn =
- get(conn, "/api/pleroma/admin/users/invite_token", %{
- "invite" => %{"expires_at" => Date.to_string(Date.utc_today())}
+ post(conn, "/api/pleroma/admin/users/invite_token", %{
+ "expires_at" => Date.to_string(Date.utc_today())
})
- token = json_response(conn, 200)
- invite = UserInviteToken.find_by_token!(token)
+ invite_json = json_response(conn, 200)
+ invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
assert invite.expires_at == Date.utc_today()
@@ -1102,13 +1090,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
test "with max_use", %{conn: conn} do
- conn =
- get(conn, "/api/pleroma/admin/users/invite_token", %{
- "invite" => %{"max_use" => 150}
- })
+ conn = post(conn, "/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
- token = json_response(conn, 200)
- invite = UserInviteToken.find_by_token!(token)
+ invite_json = json_response(conn, 200)
+ invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
refute invite.expires_at
assert invite.max_use == 150
@@ -1117,12 +1102,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
test "with max use and expires_at", %{conn: conn} do
conn =
- get(conn, "/api/pleroma/admin/users/invite_token", %{
- "invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())}
+ post(conn, "/api/pleroma/admin/users/invite_token", %{
+ "max_use" => 150,
+ "expires_at" => Date.to_string(Date.utc_today())
})
- token = json_response(conn, 200)
- invite = UserInviteToken.find_by_token!(token)
+ invite_json = json_response(conn, 200)
+ invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
assert invite.expires_at == Date.utc_today()
assert invite.max_use == 150
diff --git a/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs
index 87ee82050..89d4ca37e 100644
--- a/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs
+++ b/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs
@@ -128,6 +128,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert user["pleroma"]["hide_followers"] == true
end
+ test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/accounts/update_credentials", %{
+ hide_followers_count: "true",
+ hide_follows_count: "true"
+ })
+
+ assert user = json_response(conn, 200)
+ assert user["pleroma"]["hide_followers_count"] == true
+ assert user["pleroma"]["hide_follows_count"] == true
+ end
+
test "updates the user's skip_thread_containment option", %{conn: conn} do
user = insert(:user)
diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs
index 2ea87c5f0..6206107f7 100644
--- a/test/web/mastodon_api/views/account_view_test.exs
+++ b/test/web/mastodon_api/views/account_view_test.exs
@@ -79,6 +79,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
hide_favorites: true,
hide_followers: false,
hide_follows: false,
+ hide_followers_count: false,
+ hide_follows_count: false,
relationship: %{},
skip_thread_containment: false
}
@@ -147,6 +149,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
hide_favorites: true,
hide_followers: false,
hide_follows: false,
+ hide_followers_count: false,
+ hide_follows_count: false,
relationship: %{},
skip_thread_containment: false
}
@@ -318,6 +322,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
hide_favorites: true,
hide_followers: false,
hide_follows: false,
+ hide_followers_count: false,
+ hide_follows_count: false,
relationship: %{
id: to_string(user.id),
following: false,
@@ -361,8 +367,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
end
describe "hiding follows/following" do
- test "shows when follows/following are hidden and sets follower/following count to 0" do
- user = insert(:user, info: %{hide_followers: true, hide_follows: true})
+ test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do
+ info = %{
+ hide_followers: true,
+ hide_followers_count: true,
+ hide_follows: true,
+ hide_follows_count: true
+ }
+
+ user = insert(:user, info: info)
+
other_user = insert(:user)
{:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
@@ -370,6 +384,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
assert %{
followers_count: 0,
following_count: 0,
+ pleroma: %{hide_follows_count: true, hide_followers_count: true}
+ } = AccountView.render("account.json", %{user: user})
+ end
+
+ test "shows when follows/followers are hidden" do
+ user = insert(:user, info: %{hide_followers: true, hide_follows: true})
+ other_user = insert(:user)
+ {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+
+ assert %{
+ followers_count: 1,
+ following_count: 1,
pleroma: %{hide_follows: true, hide_followers: true}
} = AccountView.render("account.json", %{user: user})
end
diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs
index 0a2a48fb7..56e318182 100644
--- a/test/web/twitter_api/util_controller_test.exs
+++ b/test/web/twitter_api/util_controller_test.exs
@@ -775,4 +775,109 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
assert json_response(conn, 200) == %{"status" => "success"}
end
end
+
+ describe "POST /api/pleroma/change_password" do
+ setup [:valid_user]
+
+ test "without credentials", %{conn: conn} do
+ conn = post(conn, "/api/pleroma/change_password")
+ assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+ end
+
+ test "with credentials and invalid password", %{conn: conn, user: current_user} do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "hi",
+ "new_password" => "newpass",
+ "new_password_confirmation" => "newpass"
+ })
+
+ assert json_response(conn, 200) == %{"error" => "Invalid password."}
+ end
+
+ test "with credentials, valid password and new password and confirmation not matching", %{
+ conn: conn,
+ user: current_user
+ } do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "test",
+ "new_password" => "newpass",
+ "new_password_confirmation" => "notnewpass"
+ })
+
+ assert json_response(conn, 200) == %{
+ "error" => "New password does not match confirmation."
+ }
+ end
+
+ test "with credentials, valid password and invalid new password", %{
+ conn: conn,
+ user: current_user
+ } do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "test",
+ "new_password" => "",
+ "new_password_confirmation" => ""
+ })
+
+ assert json_response(conn, 200) == %{
+ "error" => "New password can't be blank."
+ }
+ end
+
+ test "with credentials, valid password and matching new password and confirmation", %{
+ conn: conn,
+ user: current_user
+ } do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "test",
+ "new_password" => "newpass",
+ "new_password_confirmation" => "newpass"
+ })
+
+ assert json_response(conn, 200) == %{"status" => "success"}
+ fetched_user = User.get_cached_by_id(current_user.id)
+ assert Comeonin.Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
+ end
+ end
+
+ describe "POST /api/pleroma/delete_account" do
+ setup [:valid_user]
+
+ test "without credentials", %{conn: conn} do
+ conn = post(conn, "/api/pleroma/delete_account")
+ assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+ end
+
+ test "with credentials and invalid password", %{conn: conn, user: current_user} do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/delete_account", %{"password" => "hi"})
+
+ assert json_response(conn, 200) == %{"error" => "Invalid password."}
+ end
+
+ test "with credentials and valid password", %{conn: conn, user: current_user} do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/delete_account", %{"password" => "test"})
+
+ assert json_response(conn, 200) == %{"status" => "success"}
+ # Wait a second for the started task to end
+ :timer.sleep(1000)
+ end
+ end
end