diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 000000000..2bed17cc0 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,3 @@ +[ + inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitignore b/.gitignore index 2858cefd5..3fbf17ba8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /*.ez /uploads /test/uploads +/.elixir_ls # Prevent committing custom emojis /priv/static/emoji/custom/* @@ -22,3 +23,6 @@ erl_crash.dump # Database setup file, some may forget to delete it /config/setup_db.psql + +.DS_Store +.env \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d852e7ae4..46fa1c74c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: elixir:1.5 +image: elixir:1.6.4 services: - postgres:9.6.2 @@ -7,6 +7,7 @@ variables: POSTGRES_DB: pleroma_test POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres + DB_HOST: postgres stages: - lint diff --git a/README.md b/README.md index 5b1c9bddd..d736354a2 100644 --- a/README.md +++ b/README.md @@ -27,27 +27,29 @@ While we don't provide docker files, other people have written very good ones. T ### Dependencies * Postgresql version 9.6 or newer -* Elixir version 1.5 or newer +* Elixir version 1.5 or newer. If your distribution only has an old version available, check [Elixir's install page](https://elixir-lang.org/install.html) or use a tool like [asdf](https://github.com/asdf-vm/asdf). * Build-essential tools ### Configuration * Run `mix deps.get` to install elixir dependencies. - * Run `mix generate_config`. This will ask you a few questions about your instance and generate a configuration file in `config/generated_config.exs`. Check that and copy it to either `config/dev.secret.exs` or `config/prod.secret.exs`. It will also create a `config/setup_db.psql`, which you need to run as PostgreSQL superuser (i.e. `sudo su postgres -c "psql -f config/setup_db.psql"`). It will setup a pleroma db user, database and will setup needed extensions that need to be set up once as superuser. + * Run `mix generate_config`. This will ask you a few questions about your instance and generate a configuration file in `config/generated_config.exs`. Check that and copy it to either `config/dev.secret.exs` or `config/prod.secret.exs`. It will also create a `config/setup_db.psql`; you may want to double-check this file in case you wanted a different username, or database name than the default. Then you need to run the script as PostgreSQL superuser (i.e. `sudo su postgres -c "psql -f config/setup_db.psql"`). It will create a pleroma db user, database and will setup needed extensions that need to be set up. Postgresql super-user privileges are only needed for this step. + + * For these next steps, the default will be to run pleroma using the dev configuration file, `config/dev.secret.exs`. To run them using the prod config file, prefix each command at the shell with `MIX_ENV=prod`. For example: `MIX_ENV=prod mix phx.server`. * Run `mix ecto.migrate` to run the database migrations. You will have to do this again after certain updates. * You can check if your instance is configured correctly by running it with `mix phx.server` and checking the instance info endpoint at `/api/v1/instance`. If it shows your uri, name and email correctly, you are configured correctly. If it shows something like `localhost:4000`, your configuration is probably wrong, unless you are running a local development setup. * The common and convenient way for adding HTTPS is by using Nginx as a reverse proxy. You can look at example Nginx configuration in `installation/pleroma.nginx`. If you need TLS/SSL certificates for HTTPS, you can look get some for free with letsencrypt: https://letsencrypt.org/ - On Debian you can use `certbot` package and command to manage letsencrypt certificates. + The simplest way to obtain and install a certificate is to use [Certbot.](https://certbot.eff.org) Depending on your specific setup, certbot may be able to get a certificate and configure your web server automatically. * [Not tested with system reboot yet!] You'll also want to set up Pleroma to be run as a systemd service. Example .service file can be found in `installation/pleroma.service` you can put it in `/etc/systemd/system/`. ## Running -By default, it listens on port 4000 (TCP), so you can access it on http://localhost:4000/ (if you are on the same machine). In case of an error it will restart automatically. +* By default, it listens on port 4000 (TCP), so you can access it on http://localhost:4000/ (if you are on the same machine). In case of an error it will restart automatically. ### Frontends Pleroma comes with two frontends. The first one, Pleroma FE, can be reached by normally visiting the site. The other one, based on the Mastodon project, can be found by visiting the /web path of your site. @@ -70,6 +72,10 @@ This is useful for running pleroma inside Tor or i2p. ## Admin Tasks +### Register a User + +Run `mix register_user `. The `name` appears on statuses, while the nickname corresponds to the user, e.g. `@nickname@instance.tld` + ### Password reset Run `mix generate_password_reset username` to generate a password reset link that you can then send to the user. diff --git a/config/config.exs b/config/config.exs index 68c054457..b0f4578d5 100644 --- a/config/config.exs +++ b/config/config.exs @@ -52,7 +52,14 @@ limit: 5000, upload_limit: 16_000_000, registrations_open: true, - federating: true + federating: true, + rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy + +config :pleroma, :mrf_simple, + media_removal: [], + media_nsfw: [], + federated_timeline_removal: [], + reject: [] config :pleroma, :media_proxy, enabled: false, diff --git a/installation/pleroma.nginx b/installation/pleroma.nginx index 61e40c508..895799a8e 100644 --- a/installation/pleroma.nginx +++ b/installation/pleroma.nginx @@ -4,7 +4,7 @@ # 1. Install your TLS certificate, possibly using Let's Encrypt. # 2. Replace 'example.tld' with your instance's domain wherever it appears. # 3. Copy this file to /etc/nginx/sites-available/ and then add a symlink to it -# in /etc/nginx/sites-enabled/ and restart nginx. +# in /etc/nginx/sites-enabled/ and run 'nginx -s reload' or restart nginx. proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=10g inactive=720m use_temp_path=off; @@ -13,6 +13,15 @@ server { listen 80; server_name example.tld; return 301 https://$server_name$request_uri; + + # Uncomment this if you need to use the 'webroot' method with certbot. Make sure + # that you also create the .well-known/acme-challenge directory structure in pleroma/priv/static and + # that is is accessible by the webserver. You may need to load this file with the ssl + # server block commented out, run certbot to get the certificate, and then uncomment it. + # + # location ~ /\.well-known/acme-challenge { + # root /pleroma/priv/static/; + # } } server { diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 515909af1..456416fbd 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -144,7 +144,7 @@ def get_custom_emoji() do @emoji end - @link_regex ~r/https?:\/\/[\w\.\/?=\-#\+%&@~\(\):]+[\w\/]/u + @link_regex ~r/https?:\/\/[\w\.\/?=\-#\+%&@~'\(\):]+[\w\/]/u def html_escape(text) do Regex.split(@link_regex, text, include_captures: true) @@ -168,7 +168,13 @@ def add_links({subs, text}) do subs = subs ++ Enum.map(links, fn {uuid, url} -> - {uuid, "#{url}"} + {:safe, link} = Phoenix.HTML.Link.link(url, to: url) + + link = + link + |> IO.iodata_to_binary() + + {uuid, link} end) {subs, uuid_text} diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index c77fd6816..e9196ae03 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -322,6 +322,16 @@ def increase_note_count(%User{} = user) do update_and_set_cache(cs) end + def decrease_note_count(%User{} = user) do + note_count = user.info["note_count"] || 0 + note_count = if note_count <= 0, do: 0, else: note_count - 1 + new_info = Map.put(user.info, "note_count", note_count) + + cs = info_changeset(user, %{info: new_info}) + + update_and_set_cache(cs) + end + def update_note_count(%User{} = user) do note_count_query = from( diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index ace230804..ec161074d 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -10,6 +10,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do @httpoison Application.get_env(:pleroma, :httpoison) + @instance Application.get_env(:pleroma, :instance) + @rewrite_policy Keyword.get(@instance, :rewrite_policy) + def get_recipients(data) do (data["to"] || []) ++ (data["cc"] || []) end @@ -17,7 +20,8 @@ def get_recipients(data) do def insert(map, local \\ true) when is_map(map) do with nil <- Activity.get_by_ap_id(map["id"]), map <- lazy_put_activity_defaults(map), - :ok <- insert_full_object(map) do + :ok <- insert_full_object(map), + {:ok, map} <- @rewrite_policy.filter(map) do {:ok, activity} = Repo.insert(%Activity{ data: map, @@ -61,7 +65,8 @@ def create(%{to: to, actor: actor, context: context, object: object} = params) d additional ), {:ok, activity} <- insert(create_data, local), - :ok <- maybe_federate(activity) do + :ok <- maybe_federate(activity), + {:ok, actor} <- User.increase_note_count(actor) do {:ok, activity} end end @@ -184,7 +189,8 @@ def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ tru with Repo.delete(object), Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), {:ok, activity} <- insert(data, local), - :ok <- maybe_federate(activity) do + :ok <- maybe_federate(activity), + {:ok, actor} <- User.decrease_note_count(user) do {:ok, activity} end end diff --git a/lib/pleroma/web/activity_pub/mrf/drop_policy.ex b/lib/pleroma/web/activity_pub/mrf/drop_policy.ex new file mode 100644 index 000000000..4333bca28 --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/drop_policy.ex @@ -0,0 +1,8 @@ +defmodule Pleroma.Web.ActivityPub.MRF.DropPolicy do + require Logger + + def filter(object) do + Logger.info("REJECTING #{inspect(object)}") + {:reject, object} + end +end diff --git a/lib/pleroma/web/activity_pub/mrf/noop_policy.ex b/lib/pleroma/web/activity_pub/mrf/noop_policy.ex new file mode 100644 index 000000000..9dd3acb04 --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/noop_policy.ex @@ -0,0 +1,5 @@ +defmodule Pleroma.Web.ActivityPub.MRF.NoOpPolicy do + def filter(object) do + {:ok, object} + end +end diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex new file mode 100644 index 000000000..4dfb0c867 --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -0,0 +1,75 @@ +defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do + alias Pleroma.User + + @mrf_policy Application.get_env(:pleroma, :mrf_simple) + + @reject Keyword.get(@mrf_policy, :reject) + defp check_reject(actor_info, object) do + if actor_info.host in @reject do + {:reject, nil} + else + {:ok, object} + end + end + + @media_removal Keyword.get(@mrf_policy, :media_removal) + defp check_media_removal(actor_info, object) do + if actor_info.host in @media_removal do + object = Map.delete(object, "attachments") + end + + {:ok, object} + end + + @media_nsfw Keyword.get(@mrf_policy, :media_nsfw) + defp check_media_nsfw(actor_info, object) do + child_object = object["object"] + + if actor_info.host in @media_nsfw and child_object["attachment"] != nil and + length(child_object["attachment"]) > 0 do + tags = (child_object["tag"] || []) ++ ["nsfw"] + child_object = Map.put(child_object, "tags", tags) + child_object = Map.put(child_object, "sensitive", true) + object = Map.put(object, "object", child_object) + end + + {:ok, object} + end + + @ftl_removal Keyword.get(@mrf_policy, :federated_timeline_removal) + defp check_ftl_removal(actor_info, object) do + if actor_info.host in @ftl_removal do + user = User.get_by_ap_id(object["actor"]) + + # flip to/cc relationship to make the post unlisted + if "https://www.w3.org/ns/activitystreams#Public" in object["to"] and + user.follower_address in object["cc"] do + to = + List.delete(object["to"], "https://www.w3.org/ns/activitystreams#Public") ++ + [user.follower_address] + + cc = + List.delete(object["cc"], user.follower_address) ++ + ["https://www.w3.org/ns/activitystreams#Public"] + + object = Map.put(object, "to", to) + object = Map.put(object, "cc", cc) + end + end + + {:ok, object} + end + + def filter(object) do + actor_info = URI.parse(object["actor"]) + + with {:ok, object} <- check_reject(actor_info, object), + {:ok, object} <- check_media_removal(actor_info, object), + {:ok, object} <- check_media_nsfw(actor_info, object), + {:ok, object} <- check_ftl_removal(actor_info, object) do + {:ok, object} + else + e -> {:reject, nil} + end + end +end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 00b9f74ff..2871a2544 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -146,7 +146,8 @@ def handle_incoming( %{"type" => "Like", "object" => object_id, "actor" => actor, "id" => id} = data ) do with %User{} = actor <- User.get_or_fetch_by_ap_id(actor), - {:ok, object} <- get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), + {:ok, object} <- + get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), {:ok, activity, object} <- ActivityPub.like(actor, object, id, false) do {:ok, activity} else @@ -158,7 +159,8 @@ def handle_incoming( %{"type" => "Announce", "object" => object_id, "actor" => actor, "id" => id} = data ) do with %User{} = actor <- User.get_or_fetch_by_ap_id(actor), - {:ok, object} <- get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), + {:ok, object} <- + get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), {:ok, activity, object} <- ActivityPub.announce(actor, object, id, false) do {:ok, activity} else @@ -209,7 +211,8 @@ def handle_incoming( end with %User{} = actor <- User.get_or_fetch_by_ap_id(actor), - {:ok, object} <- get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), + {:ok, object} <- + get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), {:ok, activity} <- ActivityPub.delete(object, false) do {:ok, activity} else diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 9e2fa1fb2..c9d0e45b2 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -175,7 +175,8 @@ def make_like_data(%User{ap_id: ap_id} = actor, %{data: %{"id" => id}} = object, def update_element_in_object(property, element, object) do with new_data <- - object.data |> Map.put("#{property}_count", length(element)) + object.data + |> Map.put("#{property}_count", length(element)) |> Map.put("#{property}s", element), changeset <- Changeset.change(object, data: new_data), {:ok, object} <- Repo.update(changeset), diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 8889b9b42..ef1170010 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -113,7 +113,6 @@ def post(user, %{"status" => status} = data) do additional: %{"cc" => cc} }) - User.increase_note_count(user) res end end diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index dfafc95f4..1a012c1b4 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -17,7 +17,7 @@ defmodule Pleroma.Web.Endpoint do Plug.Static, at: "/", from: :pleroma, - only: ~w(index.html static finmoji emoji packs sounds images instance sw.js) + only: ~w(index.html static finmoji emoji packs sounds images instance sw.js favicon.png) ) # Code reloading can be explicitly enabled under the diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index a49be0588..d506c4a41 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -528,7 +528,7 @@ def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do ^query ), limit: 20, - order_by: [desc: :inserted_at] + order_by: [desc: :id] ) statuses = Repo.all(q) ++ fetched diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 6297b7bae..11dc1806f 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -63,7 +63,8 @@ def token_exchange(conn, %{"grant_type" => "authorization_code"} = params) do client_secret: params["client_secret"] ), fixed_token = fix_padding(params["code"]), - %Authorization{} = auth <- Repo.get_by(Authorization, token: fixed_token, app_id: app.id), + %Authorization{} = auth <- + Repo.get_by(Authorization, token: fixed_token, app_id: app.id), {:ok, token} <- Token.exchange_token(app, auth) do response = %{ token_type: "Bearer", diff --git a/lib/pleroma/web/ostatus/activity_representer.ex b/lib/pleroma/web/ostatus/activity_representer.ex index 2f28c456e..921a89bd0 100644 --- a/lib/pleroma/web/ostatus/activity_representer.ex +++ b/lib/pleroma/web/ostatus/activity_representer.ex @@ -131,7 +131,8 @@ def to_simple_form(%{data: %{"object" => %{"type" => "Note"}}} = activity, user, h.(activity.data["object"]["content"] |> String.replace(~r/[\n\r]/, ""))}, {:published, h.(inserted_at)}, {:updated, h.(updated_at)}, - {:"ostatus:conversation", [ref: h.(activity.data["context"])], h.(activity.data["context"])}, + {:"ostatus:conversation", [ref: h.(activity.data["context"])], + h.(activity.data["context"])}, {:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []} ] ++ summary ++ @@ -162,7 +163,8 @@ def to_simple_form(%{data: %{"type" => "Like"}} = activity, user, with_author) d # For notes, federate the object id. {:id, h.(activity.data["object"])} ]}, - {:"ostatus:conversation", [ref: h.(activity.data["context"])], h.(activity.data["context"])}, + {:"ostatus:conversation", [ref: h.(activity.data["context"])], + h.(activity.data["context"])}, {:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []}, {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []}, {:"thr:in-reply-to", [ref: to_charlist(activity.data["object"])], []} @@ -193,7 +195,8 @@ def to_simple_form(%{data: %{"type" => "Announce"}} = activity, user, with_autho {:content, [type: 'html'], ['RT #{retweeted_activity.data["object"]["content"]}']}, {:published, h.(inserted_at)}, {:updated, h.(updated_at)}, - {:"ostatus:conversation", [ref: h.(activity.data["context"])], h.(activity.data["context"])}, + {:"ostatus:conversation", [ref: h.(activity.data["context"])], + h.(activity.data["context"])}, {:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []}, {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []}, {:"activity:object", retweeted_xml} diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex index b012abd51..bd6e92238 100644 --- a/lib/pleroma/web/ostatus/handlers/note_handler.ex +++ b/lib/pleroma/web/ostatus/handlers/note_handler.ex @@ -138,19 +138,15 @@ def handle_note(entry, doc \\ nil) do do: note |> Map.put("inReplyTo", inReplyTo), else: note ) do - res = - ActivityPub.create(%{ - to: to, - actor: actor, - context: context, - object: note, - published: date, - local: false, - additional: %{"cc" => cc} - }) - - User.increase_note_count(actor) - res + ActivityPub.create(%{ + to: to, + actor: actor, + context: context, + object: note, + published: date, + local: false, + additional: %{"cc" => cc} + }) else %Activity{} = activity -> {:ok, activity} e -> {:error, e} diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index e45c0ed8d..dc9ad2014 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -81,7 +81,10 @@ def represent_user(user, "JSON") do "href" => user.ap_id }, %{"rel" => "salmon", "href" => OStatus.salmon_path(user)}, - %{"rel" => "magic-public-key", "href" => "data:application/magic-public-key,#{magic_key}"}, + %{ + "rel" => "magic-public-key", + "href" => "data:application/magic-public-key,#{magic_key}" + }, %{"rel" => "self", "type" => "application/activity+json", "href" => user.ap_id}, %{ "rel" => "http://ostatus.org/schema/1.0/subscribe", diff --git a/priv/static/index.html b/priv/static/index.html index a7e790536..533007819 100644 --- a/priv/static/index.html +++ b/priv/static/index.html @@ -1 +1 @@ -Pleroma
\ No newline at end of file +Pleroma
\ No newline at end of file diff --git a/priv/static/instance/panel.html b/priv/static/instance/panel.html index ae9647837..7e73e4824 100644 --- a/priv/static/instance/panel.html +++ b/priv/static/instance/panel.html @@ -1,4 +1,5 @@
-

This is a Pleroma instance.

+

Welcome to Pleroma!

+

Pleroma FE | Mastodon FE

diff --git a/priv/static/static/js/app.408cea515c3032097a51.js b/priv/static/static/js/app.408cea515c3032097a51.js new file mode 100644 index 000000000..2db7c5ed1 Binary files /dev/null and b/priv/static/static/js/app.408cea515c3032097a51.js differ diff --git a/priv/static/static/js/app.408cea515c3032097a51.js.map b/priv/static/static/js/app.408cea515c3032097a51.js.map new file mode 100644 index 000000000..5ff9793da Binary files /dev/null and b/priv/static/static/js/app.408cea515c3032097a51.js.map differ diff --git a/priv/static/static/js/app.64c4246ae54f6439cb69.js b/priv/static/static/js/app.64c4246ae54f6439cb69.js deleted file mode 100644 index 3fa84f7b0..000000000 Binary files a/priv/static/static/js/app.64c4246ae54f6439cb69.js and /dev/null differ diff --git a/priv/static/static/js/app.64c4246ae54f6439cb69.js.map b/priv/static/static/js/app.64c4246ae54f6439cb69.js.map deleted file mode 100644 index e2b3fed72..000000000 Binary files a/priv/static/static/js/app.64c4246ae54f6439cb69.js.map and /dev/null differ diff --git a/priv/static/static/js/manifest.f80ee14f782f05d77e39.js b/priv/static/static/js/manifest.cdeff2a56af285544b89.js similarity index 86% rename from priv/static/static/js/manifest.f80ee14f782f05d77e39.js rename to priv/static/static/js/manifest.cdeff2a56af285544b89.js index 00282e5b8..fa511ff82 100644 Binary files a/priv/static/static/js/manifest.f80ee14f782f05d77e39.js and b/priv/static/static/js/manifest.cdeff2a56af285544b89.js differ diff --git a/priv/static/static/js/manifest.f80ee14f782f05d77e39.js.map b/priv/static/static/js/manifest.cdeff2a56af285544b89.js.map similarity index 93% rename from priv/static/static/js/manifest.f80ee14f782f05d77e39.js.map rename to priv/static/static/js/manifest.cdeff2a56af285544b89.js.map index 2d3fc34c3..a918c1acf 100644 Binary files a/priv/static/static/js/manifest.f80ee14f782f05d77e39.js.map and b/priv/static/static/js/manifest.cdeff2a56af285544b89.js.map differ diff --git a/test/formatter_test.exs b/test/formatter_test.exs index 4c65b26f2..2cf1f3f8e 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -23,21 +23,21 @@ test "turning urls into links" do text = "Hey, check out https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla." expected = - "Hey, check out https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla." + "Hey, check out https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla." assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected text = "https://mastodon.social/@lambadalambda" expected = - "https://mastodon.social/@lambadalambda" + "https://mastodon.social/@lambadalambda" assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected text = "https://mastodon.social:4000/@lambadalambda" expected = - "https://mastodon.social:4000/@lambadalambda" + "https://mastodon.social:4000/@lambadalambda" assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected @@ -47,28 +47,35 @@ test "turning urls into links" do assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected text = "http://www.cs.vu.nl/~ast/intel/" - expected = "http://www.cs.vu.nl/~ast/intel/" + expected = "http://www.cs.vu.nl/~ast/intel/" assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected text = "https://forum.zdoom.org/viewtopic.php?f=44&t=57087" expected = - "https://forum.zdoom.org/viewtopic.php?f=44&t=57087" + "https://forum.zdoom.org/viewtopic.php?f=44&t=57087" assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected text = "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" expected = - "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" + "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected text = "https://www.google.co.jp/search?q=Nasim+Aghdam" expected = - "https://www.google.co.jp/search?q=Nasim+Aghdam" + "https://www.google.co.jp/search?q=Nasim+Aghdam" + + assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected + + text = "https://en.wikipedia.org/wiki/Duff's_device" + + expected = + "https://en.wikipedia.org/wiki/Duff's_device" assert Formatter.add_links({[], text}) |> Formatter.finalize() == expected end diff --git a/test/user_test.exs b/test/user_test.exs index 6e9025f2a..9506b58fa 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -296,6 +296,25 @@ test "it increases the info->note_count property" do assert user.info["note_count"] == 2 end + test "it decreases the info->note_count property" do + note = insert(:note) + user = User.get_by_ap_id(note.data["actor"]) + + assert user.info["note_count"] == nil + + {:ok, user} = User.increase_note_count(user) + + assert user.info["note_count"] == 1 + + {:ok, user} = User.decrease_note_count(user) + + assert user.info["note_count"] == 0 + + {:ok, user} = User.decrease_note_count(user) + + assert user.info["note_count"] == 0 + end + test "it sets the info->follower_count property" do user = insert(:user) follower = insert(:user) diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index e3258ed4e..31ac10d70 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -83,16 +83,18 @@ test "adds an id to a given object if it lacks one and is a note and inserts it describe "create activities" do test "removes doubled 'to' recipients" do + user = insert(:user) + {:ok, activity} = ActivityPub.create(%{ to: ["user1", "user1", "user2"], - actor: %User{ap_id: "1"}, + actor: user, context: "", object: %{} }) assert activity.data["to"] == ["user1", "user2"] - assert activity.actor == "1" + assert activity.actor == user.ap_id assert activity.recipients == ["user1", "user2"] end end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 060ebe9f1..eb093262f 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -89,6 +89,10 @@ test "it works for incoming notices" do "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation" assert object["sensitive"] == true + + user = User.get_by_ap_id(object["actor"]) + + assert user.info["note_count"] == 1 end test "it works for incoming notices with hashtags" do @@ -102,7 +106,8 @@ test "it works for incoming follow requests" do user = insert(:user) data = - File.read!("test/fixtures/mastodon-follow-activity.json") |> Poison.decode!() + File.read!("test/fixtures/mastodon-follow-activity.json") + |> Poison.decode!() |> Map.put("object", user.ap_id) {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -118,7 +123,8 @@ test "it works for incoming likes" do {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) data = - File.read!("test/fixtures/mastodon-like.json") |> Poison.decode!() + File.read!("test/fixtures/mastodon-like.json") + |> Poison.decode!() |> Map.put("object", activity.data["object"]["id"]) {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)