Merge branch 'develop' into feature/return-link-for-password-reset
This commit is contained in:
commit
02bbcd6180
|
@ -4,11 +4,14 @@ 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
|
||||
- Mastodon API: Return `pleroma.direct_conversation_id` when creating a direct message (`POST /api/v1/statuses`)
|
||||
|
||||
## [1.1.0] - 2019-??-??
|
||||
### Security
|
||||
|
@ -23,7 +26,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
|
||||
- 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`
|
||||
|
@ -79,6 +86,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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
||||
- 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`
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@ Adding the parameter `with_muted=true` to the timeline queries will also return
|
|||
Has these additional fields under the `pleroma` object:
|
||||
|
||||
- `local`: true if the post was made on the local instance
|
||||
- `conversation_id`: the ID of the conversation the status is associated with (if any)
|
||||
- `conversation_id`: the ID of the AP context the status is associated with (if any)
|
||||
- `direct_conversation_id`: the ID of the Mastodon direct message conversation the status is associated with (if any)
|
||||
- `in_reply_to_account_acct`: the `acct` property of User entity for replied user (if any)
|
||||
- `content`: a map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`
|
||||
- `spoiler_text`: a map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`
|
||||
|
@ -50,6 +51,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 +115,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
|
||||
|
|
|
@ -39,7 +39,7 @@ Feel free to contact us to be added to this list!
|
|||
|
||||
### Nekonium
|
||||
- Homepage: [F-Droid Repository](https://repo.gdgd.jp.net/), [Google Play](https://play.google.com/store/apps/details?id=com.apps.nekonium), [Amazon](https://www.amazon.co.jp/dp/B076FXPRBC/)
|
||||
- Source: <https://git.gdgd.jp.net/lin/nekonium/>
|
||||
- Source: <https://gogs.gdgd.jp.net/lin/nekonium>
|
||||
- Contact: [@lin@pleroma.gdgd.jp.net](https://pleroma.gdgd.jp.net/users/lin)
|
||||
- Platforms: Android
|
||||
- Features: Streaming Ready
|
||||
|
@ -67,7 +67,7 @@ Feel free to contact us to be added to this list!
|
|||
## Alternative Web Interfaces
|
||||
### Brutaldon
|
||||
- Homepage: <https://jfm.carcosa.net/projects/software/brutaldon/>
|
||||
- Source Code: <https://github.com/jfmcbrayer/brutaldon>
|
||||
- Source Code: <https://git.carcosa.net/jmcbray/brutaldon>
|
||||
- Contact: [@gcupc@glitch.social](https://glitch.social/users/gcupc)
|
||||
- Features: No Streaming
|
||||
|
||||
|
|
|
@ -215,7 +215,9 @@
|
|||
]}
|
||||
]},
|
||||
|
||||
{ 5222, ejabberd_c2s, [
|
||||
%% If you want dual stack, you have to clone this entire config stanza
|
||||
%% and change the bind to "::"
|
||||
{ {5222, "0.0.0.0"}, ejabberd_c2s, [
|
||||
|
||||
%%
|
||||
%% If TLS is compiled in and you installed a SSL
|
||||
|
@ -246,7 +248,9 @@
|
|||
%% {max_stanza_size, 65536}
|
||||
%% ]},
|
||||
|
||||
{ 5269, ejabberd_s2s_in, [
|
||||
%% If you want dual stack, you have to clone this entire config stanza
|
||||
%% and change the bind to "::"
|
||||
{ {5269, "0.0.0.0"}, ejabberd_s2s_in, [
|
||||
{shaper, s2s_shaper},
|
||||
{max_stanza_size, 131072},
|
||||
{protocol_options, ["no_sslv3"]}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Pleroma do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Database do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-onl
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Ecto do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-onl
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Ecto.Migrate do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-onl
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Ecto.Rollback do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Emoji do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Instance do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Relay do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Uploads do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.User do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity.Queries do
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,7 +23,7 @@ def process(descriptions) 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 @@ def process(descriptions) 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 @@ defp print_suggestion(file, suggestion, as_list \\ false) do
|
|||
|
||||
defp print_suggestions(_file, nil), do: nil
|
||||
|
||||
defp print_suggestions(_file, ""), do: nil
|
||||
|
||||
defp print_suggestions(file, suggestions) do
|
||||
if length(suggestions) > 1 do
|
||||
IO.write(file, "Suggestions:\n")
|
||||
|
||||
if length(suggestions) > 1 do
|
||||
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
|
||||
|
|
|
@ -38,6 +38,24 @@ def change(struct, params \\ %{}) 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
|
||||
|
|
|
@ -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 @@ defp reinject_object(data) 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 @@ def fetch_object_from_id(id, options \\ []) do
|
|||
{:reject, nil}
|
||||
|
||||
{:object, data, nil} ->
|
||||
reinject_object(data)
|
||||
reinject_object(%Object{}, data)
|
||||
|
||||
{:normalize, object = %Object{}} ->
|
||||
{:ok, object}
|
||||
|
|
|
@ -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 @@ def remote_user_creation(info, params) do
|
|||
:salmon,
|
||||
:hide_followers,
|
||||
:hide_follows,
|
||||
:hide_followers_count,
|
||||
:hide_follows_count,
|
||||
:follower_count,
|
||||
:fields,
|
||||
:following_count
|
||||
|
@ -281,7 +285,9 @@ def user_upgrade(info, params, remote? \\ false) do
|
|||
:following_count,
|
||||
:hide_follows,
|
||||
:fields,
|
||||
:hide_followers
|
||||
:hide_followers,
|
||||
:hide_followers_count,
|
||||
:hide_follows_count
|
||||
])
|
||||
|> validate_fields(remote?)
|
||||
end
|
||||
|
@ -295,6 +301,8 @@ def profile_update(info, params) do
|
|||
:banner,
|
||||
:hide_follows,
|
||||
:hide_followers,
|
||||
:hide_followers_count,
|
||||
:hide_follows_count,
|
||||
:hide_favorites,
|
||||
:background,
|
||||
:show_role,
|
||||
|
@ -458,7 +466,9 @@ def follow_information_update(info, params) do
|
|||
:hide_followers,
|
||||
:hide_follows,
|
||||
:follower_count,
|
||||
:following_count
|
||||
:following_count,
|
||||
:hide_followers_count,
|
||||
:hide_follows_count
|
||||
])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.User.Query do
|
||||
|
|
|
@ -979,15 +979,7 @@ def prepare_attachments(object) 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
|
||||
|
@ -1050,8 +1042,8 @@ def upgrade_user_from_ap_id(ap_id) do
|
|||
with %User{local: false} = user <- User.get_cached_by_ap_id(ap_id),
|
||||
{:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id),
|
||||
already_ap <- User.ap_enabled?(user),
|
||||
{:ok, user} <- user |> User.upgrade_changeset(data, true) |> User.update_and_set_cache() do
|
||||
unless already_ap do
|
||||
{:ok, user} <- upgrade_user(user, data) do
|
||||
if not already_ap do
|
||||
TransmogrifierWorker.enqueue("user_upgrade", %{"user_id" => user.id})
|
||||
end
|
||||
|
||||
|
@ -1062,6 +1054,12 @@ def upgrade_user_from_ap_id(ap_id) do
|
|||
end
|
||||
end
|
||||
|
||||
defp upgrade_user(user, data) do
|
||||
user
|
||||
|> User.upgrade_changeset(data, true)
|
||||
|> User.update_and_set_cache()
|
||||
end
|
||||
|
||||
def maybe_retire_websub(ap_id) do
|
||||
# some sanity checks
|
||||
if is_binary(ap_id) && String.length(ap_id) > 8 do
|
||||
|
|
|
@ -118,30 +118,34 @@ def render("user.json", %{user: user}) 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 @@ def render("following.json", %{user: user} = opts) 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 @@ def render("following.json", %{user: user} = opts) 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 @@ def render("followers.json", %{user: user} = opts) 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
|
||||
|
@ -221,11 +227,12 @@ def render("outbox.json", %{user: user, max_id: max_qid}) do
|
|||
|
||||
activities = ActivityPub.fetch_user_activities(user, nil, params)
|
||||
|
||||
# this is sorted chronologically, so first activity is the newest (max)
|
||||
{max_id, min_id, collection} =
|
||||
if length(activities) > 0 do
|
||||
{
|
||||
Enum.at(Enum.reverse(activities), 0).id,
|
||||
Enum.at(activities, 0).id,
|
||||
Enum.at(Enum.reverse(activities), 0).id,
|
||||
Enum.map(activities, fn act ->
|
||||
{:ok, data} = Transmogrifier.prepare_outgoing(act.data)
|
||||
data
|
||||
|
|
|
@ -402,13 +402,23 @@ def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params)
|
|||
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"
|
||||
|
|
|
@ -147,6 +147,8 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
|||
[
|
||||
:no_rich_text,
|
||||
:locked,
|
||||
:hide_followers_count,
|
||||
:hide_follows_count,
|
||||
:hide_followers,
|
||||
:hide_follows,
|
||||
:hide_favorites,
|
||||
|
@ -485,7 +487,7 @@ def get_context(%{assigns: %{user: user}} = conn, %{"id" => id}) 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
|
||||
|
@ -609,7 +611,12 @@ def post_status(%{assigns: %{user: user}} = conn, %{"status" => _} = params) do
|
|||
{:ok, activity} ->
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
||||
|> try_render("status.json", %{
|
||||
activity: activity,
|
||||
for: user,
|
||||
as: :activity,
|
||||
with_direct_conversation_id: true
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -74,10 +74,18 @@ defp do_render("account.json", %{user: user} = opts) 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 @@ defp do_render("account.json", %{user: user} = opts) 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,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.OAuth.Token.CleanWorker do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.OAuth.Token.Query do
|
||||
|
|
|
@ -3,14 +3,12 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.OStatus do
|
||||
import Ecto.Query
|
||||
import Pleroma.Web.XML
|
||||
require Logger
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
|
@ -38,21 +36,13 @@ def is_representable?(%Activity{} = activity) do
|
|||
end
|
||||
end
|
||||
|
||||
def feed_path(user) do
|
||||
"#{user.ap_id}/feed.atom"
|
||||
end
|
||||
def feed_path(user), do: "#{user.ap_id}/feed.atom"
|
||||
|
||||
def pubsub_path(user) do
|
||||
"#{Web.base_url()}/push/hub/#{user.nickname}"
|
||||
end
|
||||
def pubsub_path(user), do: "#{Web.base_url()}/push/hub/#{user.nickname}"
|
||||
|
||||
def salmon_path(user) do
|
||||
"#{user.ap_id}/salmon"
|
||||
end
|
||||
def salmon_path(user), do: "#{user.ap_id}/salmon"
|
||||
|
||||
def remote_follow_path do
|
||||
"#{Web.base_url()}/ostatus_subscribe?acct={uri}"
|
||||
end
|
||||
def remote_follow_path, do: "#{Web.base_url()}/ostatus_subscribe?acct={uri}"
|
||||
|
||||
def handle_incoming(xml_string, options \\ []) do
|
||||
with doc when doc != :error <- parse_document(xml_string) do
|
||||
|
@ -217,10 +207,9 @@ def get_content(entry) do
|
|||
Get the cw that mastodon uses.
|
||||
"""
|
||||
def get_cw(entry) do
|
||||
with cw when not is_nil(cw) <- string_from_xpath("/*/summary", entry) do
|
||||
cw
|
||||
else
|
||||
_e -> nil
|
||||
case string_from_xpath("/*/summary", entry) do
|
||||
cw when not is_nil(cw) -> cw
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -232,19 +221,17 @@ def get_tags(entry) do
|
|||
end
|
||||
|
||||
def maybe_update(doc, user) do
|
||||
if "true" == string_from_xpath("//author[1]/ap_enabled", doc) do
|
||||
case string_from_xpath("//author[1]/ap_enabled", doc) do
|
||||
"true" ->
|
||||
Transmogrifier.upgrade_user_from_ap_id(user.ap_id)
|
||||
else
|
||||
|
||||
_ ->
|
||||
maybe_update_ostatus(doc, user)
|
||||
end
|
||||
end
|
||||
|
||||
def maybe_update_ostatus(doc, user) do
|
||||
old_data = %{
|
||||
avatar: user.avatar,
|
||||
bio: user.bio,
|
||||
name: user.name
|
||||
}
|
||||
old_data = Map.take(user, [:bio, :avatar, :name])
|
||||
|
||||
with false <- user.local,
|
||||
avatar <- make_avatar_object(doc),
|
||||
|
@ -279,21 +266,28 @@ def find_make_or_update_actor(doc) do
|
|||
end
|
||||
end
|
||||
|
||||
@spec find_or_make_user(String.t()) :: {:ok, User.t()}
|
||||
def find_or_make_user(uri) do
|
||||
query = from(user in User, where: user.ap_id == ^uri)
|
||||
|
||||
user = Repo.one(query)
|
||||
|
||||
if is_nil(user) do
|
||||
make_user(uri)
|
||||
else
|
||||
{:ok, user}
|
||||
case User.get_by_ap_id(uri) do
|
||||
%User{} = user -> {:ok, user}
|
||||
_ -> make_user(uri)
|
||||
end
|
||||
end
|
||||
|
||||
@spec make_user(String.t(), boolean()) :: {:ok, User.t()} | {:error, any()}
|
||||
def make_user(uri, update \\ false) do
|
||||
with {:ok, info} <- gather_user_info(uri) do
|
||||
data = %{
|
||||
with false <- update,
|
||||
%User{} = user <- User.get_cached_by_ap_id(info["uri"]) do
|
||||
{:ok, user}
|
||||
else
|
||||
_e -> User.insert_or_update_user(build_user_data(info))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp build_user_data(info) do
|
||||
%{
|
||||
name: info["name"],
|
||||
nickname: info["nickname"] <> "@" <> info["host"],
|
||||
ap_id: info["uri"],
|
||||
|
@ -301,14 +295,6 @@ def make_user(uri, update \\ false) do
|
|||
avatar: info["avatar"],
|
||||
bio: info["bio"]
|
||||
}
|
||||
|
||||
with false <- update,
|
||||
%User{} = user <- User.get_cached_by_ap_id(data.ap_id) do
|
||||
{:ok, user}
|
||||
else
|
||||
_e -> User.insert_or_update_user(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: Just takes the first one for now.
|
||||
|
@ -319,23 +305,23 @@ def make_avatar_object(author_doc, rel \\ "avatar") do
|
|||
if href do
|
||||
%{
|
||||
"type" => "Image",
|
||||
"url" => [
|
||||
%{
|
||||
"type" => "Link",
|
||||
"mediaType" => type,
|
||||
"href" => href
|
||||
}
|
||||
]
|
||||
"url" => [%{"type" => "Link", "mediaType" => type, "href" => href}]
|
||||
}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@spec gather_user_info(String.t()) :: {:ok, map()} | {:error, any()}
|
||||
def gather_user_info(username) do
|
||||
with {:ok, webfinger_data} <- WebFinger.finger(username),
|
||||
{:ok, feed_data} <- Websub.gather_feed_data(webfinger_data["topic"]) do
|
||||
{:ok, Map.merge(webfinger_data, feed_data) |> Map.put("fqn", username)}
|
||||
data =
|
||||
webfinger_data
|
||||
|> Map.merge(feed_data)
|
||||
|> Map.put("fqn", username)
|
||||
|
||||
{:ok, data}
|
||||
else
|
||||
e ->
|
||||
Logger.debug(fn -> "Couldn't gather info for #{username}" end)
|
||||
|
@ -371,10 +357,7 @@ def get_atom_url(body) do
|
|||
def fetch_activity_from_atom_url(url, options \\ []) do
|
||||
with true <- String.starts_with?(url, "http"),
|
||||
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
||||
HTTP.get(
|
||||
url,
|
||||
[{:Accept, "application/atom+xml"}]
|
||||
) do
|
||||
HTTP.get(url, [{:Accept, "application/atom+xml"}]) do
|
||||
Logger.debug("Got document from #{url}, handling...")
|
||||
handle_incoming(body, options)
|
||||
else
|
||||
|
|
|
@ -55,12 +55,11 @@ def feed_redirect(conn, %{"nickname" => nickname}) do
|
|||
|
||||
def feed(conn, %{"nickname" => nickname} = params) do
|
||||
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
|
||||
query_params =
|
||||
Map.take(params, ["max_id"])
|
||||
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
|
||||
|
||||
activities =
|
||||
ActivityPub.fetch_public_activities(query_params)
|
||||
params
|
||||
|> Map.take(["max_id"])
|
||||
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
|
||||
|> ActivityPub.fetch_public_activities()
|
||||
|> Enum.reverse()
|
||||
|
||||
response =
|
||||
|
@ -98,8 +97,7 @@ def salmon_incoming(conn, _) do
|
|||
|
||||
Federator.incoming_doc(doc)
|
||||
|
||||
conn
|
||||
|> send_resp(200, "")
|
||||
send_resp(conn, 200, "")
|
||||
end
|
||||
|
||||
def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid})
|
||||
|
|
|
@ -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)
|
||||
|
|
3
mix.exs
3
mix.exs
|
@ -174,7 +174,8 @@ defp aliases 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
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ActivityTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.CaptchaTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ConfigTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ActivityExpirationWorkerTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ScheduledActivityDaemonTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emails.AdminEmailTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emails.MailerTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emails.UserEmailTest do
|
||||
|
|
|
@ -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"}
|
|
@ -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"}
|
|
@ -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"}
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.FormatterTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTMLTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ListTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.NotificationTest do
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
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 @@ test "does not fetch unknown objects when fetch_remote is false" 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Plugs.AuthenticationPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.CacheControlTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.RuntimeStaticPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Plugs.OAuthPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Plugs.OAuthScopesPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Plugs.SetFormatPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Plugs.SetLocalePlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.UploadedMediaPlugTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ScheduledActivityTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Captcha.Mock do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ConnCase do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.DataCase do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Tests.Helpers do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule HttpRequestMock do
|
||||
|
@ -1004,6 +1004,10 @@ def get("https://skippers-bin.com/users/7v1w1r8ce6", _, _, _) 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)}, #{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule MRFModuleMock do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Tests.ObanHelpers do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.WebPushHttpClientMock do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-onl
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Ecto.MigrateTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.RelayTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.UserTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: []
|
||||
|
@ -7,3 +7,8 @@
|
|||
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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.UploadTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.UserSearchTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.UserTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.RelayTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
||||
|
|
|
@ -105,10 +105,20 @@ test "sets totalItems to zero when followers are hidden" 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,42 @@ test "sets totalItems to zero when follows are hidden" 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
|
||||
|
||||
test "outbox paginates correctly" do
|
||||
user = insert(:user)
|
||||
|
||||
posts =
|
||||
for i <- 0..25 do
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "post #{i}"})
|
||||
activity
|
||||
end
|
||||
|
||||
# outbox sorts chronologically, newest first, with ten per page
|
||||
posts = Enum.reverse(posts)
|
||||
|
||||
%{"first" => %{"next" => next_url}} =
|
||||
UserView.render("outbox.json", %{user: user, max_id: nil})
|
||||
|
||||
next_id = Enum.at(posts, 9).id
|
||||
assert next_url =~ next_id
|
||||
|
||||
%{"next" => next_url} = UserView.render("outbox.json", %{user: user, max_id: next_id})
|
||||
next_id = Enum.at(posts, 19).id
|
||||
assert next_url =~ next_id
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
||||
|
@ -574,18 +574,6 @@ test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: us
|
|||
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)
|
||||
|
@ -1066,7 +1054,7 @@ test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" 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})
|
||||
|
||||
|
@ -1078,10 +1066,10 @@ test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" 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
|
||||
|
@ -1090,12 +1078,12 @@ test "without options", %{conn: conn} 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()
|
||||
|
@ -1104,13 +1092,10 @@ test "with expires_at", %{conn: conn} 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
|
||||
|
@ -1119,12 +1104,13 @@ test "with max_use", %{conn: conn} 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.SearchTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.FederatorTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Instances.InstanceTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.InstancesTest do
|
||||
|
|
|
@ -128,6 +128,22 @@ test "updates the user's hide_followers status", %{conn: conn} 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)
|
||||
|
||||
|
|
|
@ -296,7 +296,9 @@ test "posting a direct status", %{conn: conn} do
|
|||
conn
|
||||
|> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
|
||||
|
||||
assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200)
|
||||
assert %{"id" => id} = response = json_response(conn, 200)
|
||||
assert response["visibility"] == "direct"
|
||||
assert response["pleroma"]["direct_conversation_id"]
|
||||
assert activity = Activity.get_by_id(id)
|
||||
assert activity.recipients == [user2.ap_id, conn.assigns[:user].ap_id]
|
||||
assert activity.data["to"] == [user2.ap_id]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
||||
|
@ -79,6 +79,8 @@ test "Represent a user account" 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 @@ test "Represent a Service(bot) account" 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 @@ test "represent an embedded relationship" 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 @@ test "sanitizes display names" 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 @@ test "shows when follows/following are hidden and sets follower/following count
|
|||
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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.ListViewTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue