From 83354d834d1238da8b91441dfb7224a0531165f6 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 31 Aug 2020 17:26:08 +0200 Subject: [PATCH 1/4] Fix relay outbox endpoint Signed-off-by: Thomas Citharel --- lib/federation/activity_pub/activity_pub.ex | 16 +++++++++++++--- lib/mobilizon/actors/actor.ex | 1 + lib/mobilizon/discussions/discussions.ex | 10 ++++++++++ lib/mobilizon/events/events.ex | 10 ++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/federation/activity_pub/activity_pub.ex b/lib/federation/activity_pub/activity_pub.ex index d6447d88f..e7b985ac0 100644 --- a/lib/federation/activity_pub/activity_pub.ex +++ b/lib/federation/activity_pub/activity_pub.ex @@ -769,12 +769,22 @@ defmodule Mobilizon.Federation.ActivityPub do Return all public activities (events & comments) for an actor """ @spec fetch_public_activities_for_actor(Actor.t(), integer(), integer()) :: map() - def fetch_public_activities_for_actor(%Actor{} = actor, page \\ 1, limit \\ 10) do + def fetch_public_activities_for_actor(%Actor{id: actor_id} = actor, page \\ 1, limit \\ 10) do + %Actor{id: relay_actor_id} = Relay.get_actor() + %Page{total: total_events, elements: events} = - Events.list_public_events_for_actor(actor, page, limit) + if actor_id == relay_actor_id do + Events.list_public_local_events(page, limit) + else + Events.list_public_events_for_actor(actor, page, limit) + end %Page{total: total_comments, elements: comments} = - Discussions.list_public_comments_for_actor(actor, page, limit) + if actor_id == relay_actor_id do + Discussions.list_local_comments(page, limit) + else + Discussions.list_public_comments_for_actor(actor, page, limit) + end event_activities = Enum.map(events, &event_to_activity/1) comment_activities = Enum.map(comments, &comment_to_activity/1) diff --git a/lib/mobilizon/actors/actor.ex b/lib/mobilizon/actors/actor.ex index 72549c22b..d59154fa6 100644 --- a/lib/mobilizon/actors/actor.ex +++ b/lib/mobilizon/actors/actor.ex @@ -394,6 +394,7 @@ defmodule Mobilizon.Actors.Actor do "keys" => Crypto.generate_rsa_2048_private_key(), "preferred_username" => "relay", "domain" => nil, + "visibility" => :public, "type" => :Application } diff --git a/lib/mobilizon/discussions/discussions.ex b/lib/mobilizon/discussions/discussions.ex index cfc79d7e5..cd6e7f523 100644 --- a/lib/mobilizon/discussions/discussions.ex +++ b/lib/mobilizon/discussions/discussions.ex @@ -239,6 +239,16 @@ defmodule Mobilizon.Discussions do Repo.all(from(c in Comment, where: c.visibility == ^:public)) end + @spec list_local_comments(integer | nil, integer | nil) :: Page.t() + def list_local_comments(page \\ nil, limit \\ nil) do + Comment + |> where([c], c.visibility == ^:public) + |> where([c], is_nil(c.deleted_at)) + |> where([c], is_nil(c.discussion_id)) + |> preload_for_comment() + |> Page.build_page(page, limit) + end + @doc """ Returns the list of public comments for the actor. """ diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index 6a5248ce0..a6f27cb52 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -375,6 +375,16 @@ defmodule Mobilizon.Events do |> Repo.stream() end + @spec list_public_local_events(integer | nil, integer | nil) :: Page.t() + def list_public_local_events(page \\ nil, limit \\ nil) do + Event + |> filter_public_visibility() + |> filter_draft() + |> filter_local() + |> preload_for_event() + |> Page.build_page(page, limit) + end + @doc """ Returns the list of events with the same tags. """ From 6148cfdaac95167c1112bf89e3a3a5cb2c15260a Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 2 Sep 2020 08:59:59 +0200 Subject: [PATCH 2/4] Allow to refresh instance outbox when they accept subscription Signed-off-by: Thomas Citharel --- js/package.json | 4 +- js/yarn.lock | 387 +++++++++++------- lib/federation/activity_pub/activity_pub.ex | 33 +- lib/federation/activity_pub/fetcher.ex | 1 + lib/federation/activity_pub/refresher.ex | 30 +- lib/federation/activity_pub/relay.ex | 4 + lib/federation/activity_pub/transmogrifier.ex | 12 +- .../activity_stream/converter/event.ex | 88 ++-- lib/graphql/api/follows.ex | 4 + lib/graphql/resolvers/admin.ex | 2 +- lib/mobilizon/actors/actors.ex | 6 +- lib/mobilizon/events/events.ex | 5 +- lib/mobilizon/tombstone.ex | 5 +- lib/service/formatter/html.ex | 4 +- lib/service/workers/helper.ex | 2 + lib/web/views/activity_pub/actor_view.ex | 2 +- mix.lock | 14 +- .../20200901101307_fix_relay_visibility.exs | 19 + .../activity_pub/transmogrifier_test.exs | 20 +- .../activity_pub_controller_test.exs | 12 +- 20 files changed, 427 insertions(+), 227 deletions(-) create mode 100644 priv/repo/migrations/20200901101307_fix_relay_visibility.exs diff --git a/js/package.json b/js/package.json index 0043591a3..1a79301f4 100644 --- a/js/package.json +++ b/js/package.json @@ -65,8 +65,8 @@ "@types/prosemirror-state": "^1.2.4", "@types/prosemirror-view": "^1.11.4", "@types/vuedraggable": "^2.23.0", - "@typescript-eslint/eslint-plugin": "^3.10.1", - "@typescript-eslint/parser": "^3.10.1", + "@typescript-eslint/eslint-plugin": "^4.0.1", + "@typescript-eslint/parser": "^4.0.1", "@vue/cli-plugin-babel": "~4.5.4", "@vue/cli-plugin-e2e-cypress": "~4.5.4", "@vue/cli-plugin-eslint": "~4.5.4", diff --git a/js/yarn.lock b/js/yarn.lock index 454b7e014..9056d2d27 100644 --- a/js/yarn.lock +++ b/js/yarn.lock @@ -82,18 +82,18 @@ semver "^5.5.0" "@babel/core@^7.11.0", "@babel/core@^7.7.5": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229" - integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.5.tgz#6ad96e2f71899ea3f9b651f0a911e85205d1ff6d" + integrity sha512-fsEANVOcZHzrsV6dMVWqpSeXClq3lNbYrfFGme6DE25FQWe7pyeYpXyx9guqUnpy466JLzZ8z4uwSr2iv60V5Q== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.4" + "@babel/generator" "^7.11.5" "@babel/helper-module-transforms" "^7.11.0" "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.4" + "@babel/parser" "^7.11.5" "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.0" - "@babel/types" "^7.11.0" + "@babel/traverse" "^7.11.5" + "@babel/types" "^7.11.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -101,16 +101,16 @@ lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" - source-map "^0.5.0" + source-map "^0.6.1" -"@babel/generator@^7.11.0", "@babel/generator@^7.11.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be" - integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g== +"@babel/generator@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.5.tgz#a5582773425a468e4ba269d9a1f701fbca6a7a82" + integrity sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.11.5" jsesc "^2.5.1" - source-map "^0.5.0" + source-map "^0.6.1" "@babel/helper-annotate-as-pure@^7.10.4": version "7.10.4" @@ -319,10 +319,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca" - integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA== +"@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== "@babel/plugin-proposal-async-generator-functions@^7.10.4": version "7.10.5" @@ -737,9 +737,9 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-runtime@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz#e27f78eb36f19448636e05c33c90fd9ad9b8bccf" - integrity sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.5.tgz#f108bc8e0cf33c37da031c097d1df470b3a293fc" + integrity sha512-9aIoee+EhjySZ6vY5hnLjigHzunBlscx9ANKutkeWTJTx6m5Rbq6Ic01tLvO54lSusR+BxV7u4UDdCmXv5aagg== dependencies: "@babel/helper-module-imports" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" @@ -800,9 +800,9 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/preset-env@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" - integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" + integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== dependencies: "@babel/compat-data" "^7.11.0" "@babel/helper-compilation-targets" "^7.10.4" @@ -866,7 +866,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.10.4" "@babel/plugin-transform-unicode-regex" "^7.10.4" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.0" + "@babel/types" "^7.11.5" browserslist "^4.12.0" core-js-compat "^3.6.2" invariant "^2.2.2" @@ -915,25 +915,25 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" - integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" + integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.0" + "@babel/generator" "^7.11.5" "@babel/helper-function-name" "^7.10.4" "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.0" - "@babel/types" "^7.11.0" + "@babel/parser" "^7.11.5" + "@babel/types" "^7.11.5" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.4.4", "@babel/types@^7.6.0", "@babel/types@^7.6.1", "@babel/types@^7.9.6": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" - integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== +"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4", "@babel/types@^7.6.0", "@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" + integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" @@ -957,6 +957,22 @@ debug "^3.1.0" lodash.once "^4.1.1" +"@eslint/eslintrc@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085" + integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + lodash "^4.17.19" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@graphql-cli/common@4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@graphql-cli/common/-/common-4.0.0.tgz#a14d382b1e744b784eebde4cb98fadd30fd5e3b2" @@ -988,51 +1004,52 @@ tmp "0.2.1" tslib "^2.0.0" -"@graphql-tools/delegate@6.1.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-6.1.0.tgz#ceda597f091d5aed8065df3cea8d59858e35782e" - integrity sha512-LBulO9tEx+4TvRIY3yCivCYdtI18BpDX/qlSs+K7AuTgCH8eJ/S/FinFRTpTK/9bQwXnBh/d9WjiiRekUCiW6g== +"@graphql-tools/delegate@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-6.2.0.tgz#56fce5ea5fdd69654d0f4f4db674a1e09827132a" + integrity sha512-jYwg6MuErovAHXhyReTSgRTzdvPB60VEO02KGZskaD5WPqCQy6oqYBetXOp1yG6PBwJvxCTpMKuZvyPVLRM9ww== dependencies: "@ardatan/aggregate-error" "0.0.1" - "@graphql-tools/schema" "6.1.0" - "@graphql-tools/utils" "6.1.0" + "@graphql-tools/schema" "6.2.0" + "@graphql-tools/utils" "6.2.0" + dataloader "2.0.0" is-promise "4.0.0" tslib "~2.0.1" "@graphql-tools/graphql-file-loader@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.1.0.tgz#8b0d8dc7ffd0417c68ad97a916a0ea1841d55d36" - integrity sha512-UZsCx/JJPlkCPYoKJhOcMpDYRx0RagBJ/0gVjgUyiykGJyl8QqTUz34QZhRFg5WGPWcEyT8z18w5WocPCXwK+g== + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.2.0.tgz#7dbb4b4562b1cd3eb5c1a7359a53bf0711d6e537" + integrity sha512-anl/fc2KTLF2Eu5Fd9fRYy+N22QBZskP2uKAqyiaJFPiIAOXWAUjK/WJ4uWAAjkGhEnseK0M8hUudgW36w8Smg== dependencies: - "@graphql-tools/import" "6.1.0" - "@graphql-tools/utils" "6.1.0" + "@graphql-tools/import" "6.2.0" + "@graphql-tools/utils" "6.2.0" fs-extra "9.0.1" tslib "~2.0.1" -"@graphql-tools/import@6.1.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.1.0.tgz#82994007a99ba93db3ad95a5c51a59d9c9e84439" - integrity sha512-MuW9v8w8hc6GvsWQH41NnOAr1f7bkV4E6AWMYpndAHPcuwwGHiLHizLCEjbNovzdoA8N9h3sMenhQyRpCAiEzg== +"@graphql-tools/import@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.2.0.tgz#be54d3ab781efb9e34e6289f03c3a4e55744b0be" + integrity sha512-fYLyzAW3RKKfyPO+0nEA86yUP2V2uctdsZVZEamJ9MtjW+UhZf9kbR+NBuX/FbFAQR+F7UMe5GSPjUTKC13CEg== dependencies: fs-extra "9.0.1" resolve-from "5.0.0" "@graphql-tools/json-file-loader@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-6.1.0.tgz#1112dffa2936fb157185afd693e3de6a1805705c" - integrity sha512-U5+aU4Bi9Se2+rFE0lwARHii1TyKtVG+WPNtBM1YJdgQ800/jrgjSCBl2Js/bd2YkICMLz++lCehyQSgrLpIsg== + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-6.2.0.tgz#e206cd9663fbd02613bba504526d6446be930a9d" + integrity sha512-kpvYLGuxcq3V9cr996YOCAkw7F/4pC1JY1KxvI3360G0mYVVZcA8Q/XcxcwPwPZrBHDJMHhXvTRZD+svQ49Rxw== dependencies: - "@graphql-tools/utils" "6.1.0" + "@graphql-tools/utils" "6.2.0" fs-extra "9.0.1" tslib "~2.0.1" "@graphql-tools/load@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-6.1.0.tgz#0880050722ac4297c6f782a84b8b87ce464933d8" - integrity sha512-4puWwWPvLKskTtabMXlYW4fdm5yaAgHNwJeUhs3/ftX9mrJOa8HnfIxULZOES9XEbaRoaVQ0wPRBjJKcTBJ7CQ== + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-6.2.0.tgz#b1db775824af76857d3e7d06886945d5adc24279" + integrity sha512-ZsxPXMpLOjNh88Q2XtDmMTP65tQfknZjCgWm9vq+FxlUh//7Z8q6WiChogIEJ9g8G0+XKmLEcA+Vi4L45QX9GA== dependencies: - "@graphql-tools/merge" "6.1.0" - "@graphql-tools/utils" "6.1.0" + "@graphql-tools/merge" "6.2.0" + "@graphql-tools/utils" "6.2.0" globby "11.0.1" import-from "3.0.0" is-glob "4.0.1" @@ -1041,54 +1058,54 @@ unixify "1.0.0" valid-url "1.0.9" -"@graphql-tools/merge@6.1.0", "@graphql-tools/merge@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.1.0.tgz#5c9d09b2387514f4b2d679a2e2b15335cee95f15" - integrity sha512-dD7J/LELhy87+5V8pko5EhSx2leoRIT02V5coa6S19PTiNrVqCJU/fMMKdWC1FmHSWUYOf+wZhItsilUxPr7XQ== +"@graphql-tools/merge@6.2.0", "@graphql-tools/merge@^6.0.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.0.tgz#452a84b996b7fef38fe6f48985ba21ffd8f40d6d" + integrity sha512-q2bnFhdw6ssBzIlTkyUGPzBThLHgwuTVCRvjjCepegQCKGzwDypve0n+EMBUnoaOcJ3JRgQHR3eStP2x/S0AYw== dependencies: - "@graphql-tools/schema" "6.1.0" - "@graphql-tools/utils" "6.1.0" + "@graphql-tools/schema" "6.2.0" + "@graphql-tools/utils" "6.2.0" tslib "~2.0.1" -"@graphql-tools/schema@6.1.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-6.1.0.tgz#8176bf3b56dc1e78243a5f01646c7abbc9921d26" - integrity sha512-AZflTf9HU3Uy8UgUwxwFXN9Lf+9D36LBoDRIxPRhsj6EtawbwCqsd3UFwNek0OgiwNi3BL2b+D+6QEcw2IOsDA== +"@graphql-tools/schema@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-6.2.0.tgz#41171cdaeb7d7835a458628f0c546fef2bae3a64" + integrity sha512-wlAIgN6pMgRaruiJqlZLIe+FM834ZYif/P7evCbG71sm7Ou8t0n+dkpf8+qZAa7D+PWO9G96BF1l2NPUlM+KvA== dependencies: - "@graphql-tools/utils" "6.1.0" + "@graphql-tools/utils" "6.2.0" tslib "~2.0.1" "@graphql-tools/url-loader@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-6.1.0.tgz#36a7cb6270548d3e800acebc25ecf65cb8ba6214" - integrity sha512-AzTDZPQqHv2jrTrKhPgLbeWBhEjwFMAFnRKPsaGnSxkZWAeTeA4XevbWS4wl9jho0klTtSRBbKnNBp+dxbpmwA== + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-6.2.0.tgz#2c764c15457e0a37e3551617fd8490ccf21f0ee1" + integrity sha512-bPktwMT42tvsPIlJYQ4bwjnQKhOSwCsV/R81T0tsoh+UbKR2/QxccSQCoNJAUIxP6hXfR+Sc1wMXUw7m8/akrg== dependencies: - "@graphql-tools/delegate" "6.1.0" - "@graphql-tools/utils" "6.1.0" - "@graphql-tools/wrap" "6.1.0" + "@graphql-tools/delegate" "6.2.0" + "@graphql-tools/utils" "6.2.0" + "@graphql-tools/wrap" "6.2.0" "@types/websocket" "1.0.1" cross-fetch "3.0.5" subscriptions-transport-ws "0.9.18" tslib "~2.0.1" valid-url "1.0.9" - websocket "1.0.31" + websocket "1.0.32" -"@graphql-tools/utils@6.1.0", "@graphql-tools/utils@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-6.1.0.tgz#a8ab67bb8d8a879f40d29b334f48de6e6be71c41" - integrity sha512-YcyslZ/8rk5nQOGnkEDp/xi6Xphu0mgjh5LTZ1qUio5P+d95/9MW44cPdmi3Feg4kO8u+1GcPC+685hFpJlZJw== +"@graphql-tools/utils@6.2.0", "@graphql-tools/utils@^6.0.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-6.2.0.tgz#5dc2ccec9d7fa098b9c76bddfd8a7ca64fc3fe9c" + integrity sha512-Z5ONje6tGNvBzGwo/8eIafr98mwuvWpi3IwPp8CKHKjTBAKlUxY8hlwSn+bEMPyuA9uH/7nHWz4lamRQQEHAhg== dependencies: "@ardatan/aggregate-error" "0.0.1" camel-case "4.1.1" -"@graphql-tools/wrap@6.1.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-6.1.0.tgz#52451574dc667a423b66ad05720add03cbecb7b8" - integrity sha512-sJ4ePvgQ2AKWGQ75hockh1k+0BhPbr7SZqe4T/HKNMCuATNiRi0m78FoxHTp/JODMKRPfhadunD74CXrxupy6A== +"@graphql-tools/wrap@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-6.2.0.tgz#29fb7ff740d04777aa1bde8edb66ba6898dc8621" + integrity sha512-I7EAvY6x6cBB92j+IrZLE3meYUdmHNK8r/TvHXJ8SmgMJGlt4z8bjOr7WmYdMPufyVdHBSGwECqjWcxOhSxLsA== dependencies: - "@graphql-tools/delegate" "6.1.0" - "@graphql-tools/schema" "6.1.0" - "@graphql-tools/utils" "6.1.0" + "@graphql-tools/delegate" "6.2.0" + "@graphql-tools/schema" "6.2.0" + "@graphql-tools/utils" "6.2.0" aggregate-error "3.1.0" is-promise "4.0.0" tslib "~2.0.1" @@ -1282,18 +1299,18 @@ integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== "@types/express-serve-static-core@*": - version "4.17.9" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz#2d7b34dcfd25ec663c25c85d76608f8b249667f1" - integrity sha512-DG0BYg6yO+ePW+XoDENYz8zhNGC3jDDEpComMYn7WJc4mY1Us8Rw9ax2YhJXxpyk2SF47PQAoQ0YyVT1a0bEkA== + version "4.17.12" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.12.tgz#9a487da757425e4f267e7d1c5720226af7f89591" + integrity sha512-EaEdY+Dty1jEU7U6J4CUWwxL+hyEGMkO5jan5gplfegUgCUsIUWqXxqw47uGjimeT4Qgkz/XUfwoau08+fgvKA== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" "@types/express@*": - version "4.17.7" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.7.tgz#42045be6475636d9801369cd4418ef65cdb0dd59" - integrity sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ== + version "4.17.8" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.8.tgz#3df4293293317e61c60137d273a2e96cd8d5f27a" + integrity sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "*" @@ -1335,9 +1352,9 @@ integrity sha512-6QWXsuqzfUMfsg1DTJan/MfUi80LGS1TOohSqxlgpBZEHH344xpl3LzgANTp7PPWf7Z/9S0l14RMQPF0vH7MIg== "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/json5@^0.0.29": version "0.0.29" @@ -1561,12 +1578,13 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== -"@typescript-eslint/eslint-plugin@^3.10.1": - version "3.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz#7e061338a1383f59edc204c605899f93dc2e2c8f" - integrity sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ== +"@typescript-eslint/eslint-plugin@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.1.tgz#88bde9239e29d688315718552cf80a3490491017" + integrity sha512-pQZtXupCn11O4AwpYVUX4PDFfmIJl90ZgrEBg0CEcqlwvPiG0uY81fimr1oMFblZnpKAq6prrT9a59pj1x58rw== dependencies: - "@typescript-eslint/experimental-utils" "3.10.1" + "@typescript-eslint/experimental-utils" "4.0.1" + "@typescript-eslint/scope-manager" "4.0.1" debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" @@ -1584,7 +1602,19 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@^3.0.0", "@typescript-eslint/parser@^3.10.1": +"@typescript-eslint/experimental-utils@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.1.tgz#7d9a3ab6821ad5274dad2186c1aa0d93afd696eb" + integrity sha512-gAqOjLiHoED79iYTt3F4uSHrYmg/GPz/zGezdB0jAdr6S6gwNiR/j7cTZ8nREKVzMVKLd9G3xbg1sV9GClW3sw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.0.1" + "@typescript-eslint/types" "4.0.1" + "@typescript-eslint/typescript-estree" "4.0.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@^3.0.0": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.10.1.tgz#1883858e83e8b442627e1ac6f408925211155467" integrity sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw== @@ -1595,11 +1625,34 @@ "@typescript-eslint/typescript-estree" "3.10.1" eslint-visitor-keys "^1.1.0" +"@typescript-eslint/parser@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.0.1.tgz#73772080db7a7a4534a35d719e006f503e664dc3" + integrity sha512-1+qLmXHNAWSQ7RB6fdSQszAiA7JTwzakj5cNYjBTUmpH2cqilxMZEIV+DRKjVZs8NzP3ALmKexB0w/ExjcK9Iw== + dependencies: + "@typescript-eslint/scope-manager" "4.0.1" + "@typescript-eslint/types" "4.0.1" + "@typescript-eslint/typescript-estree" "4.0.1" + debug "^4.1.1" + +"@typescript-eslint/scope-manager@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.0.1.tgz#24d93c3000bdfcc5a157dc4d32b742405a8631b5" + integrity sha512-u3YEXVJ8jsj7QCJk3om0Y457fy2euEOkkzxIB/LKU3MdyI+FJ2gI0M4aKEaXzwCSfNDiZ13a3lDo5DVozc+XLQ== + dependencies: + "@typescript-eslint/types" "4.0.1" + "@typescript-eslint/visitor-keys" "4.0.1" + "@typescript-eslint/types@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== +"@typescript-eslint/types@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.0.1.tgz#1cf72582f764931f085cb8230ff215980fe467b2" + integrity sha512-S+gD3fgbkZYW2rnbjugNMqibm9HpEjqZBZkTiI3PwbbNGWmAcxolWIUwZ0SKeG4Dy2ktpKKaI/6+HGYVH8Qrlg== + "@typescript-eslint/typescript-estree@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" @@ -1614,6 +1667,20 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.1.tgz#29a43c7060641ec51c902d9f50ac7c5866ec479f" + integrity sha512-zGzleORFXrRWRJAMLTB2iJD1IZbCPkg4hsI8mGdpYlKaqzvKYSEWVAYh14eauaR+qIoZVWrXgYSXqLtTlxotiw== + dependencies: + "@typescript-eslint/types" "4.0.1" + "@typescript-eslint/visitor-keys" "4.0.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/visitor-keys@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" @@ -1621,6 +1688,14 @@ dependencies: eslint-visitor-keys "^1.1.0" +"@typescript-eslint/visitor-keys@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.1.tgz#d4e8de62775f2a6db71c7e8539633680039fdd6c" + integrity sha512-yBSqd6FjnTzbg5RUy9J+9kJEyQjTI34JdGMJz+9ttlJzLCnGkBikxw+N5n2VDcc3CesbIEJ0MnZc5uRYnrEnCw== + dependencies: + "@typescript-eslint/types" "4.0.1" + eslint-visitor-keys "^2.0.0" + "@vue/babel-helper-vue-jsx-merge-props@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" @@ -3193,6 +3268,13 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +bufferutil@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.1.tgz#3a177e8e5819a1243fe16b63a199951a7ad8d4a7" + integrity sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA== + dependencies: + node-gyp-build "~3.7.0" + builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -3394,9 +3476,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000929, caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111: - version "1.0.30001120" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001120.tgz#cd21d35e537214e19f7b9f4f161f7b0f2710d46c" - integrity sha512-JBP68okZs1X8D7MQTY602jxMYBmXEKOFkzTBaNSkubooMPFOAv2TXWaKle7qgHpjLDhUzA/TMT0qsNleVyXGUQ== + version "1.0.30001122" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001122.tgz#2c8ff631330d986a07a7ba7125cce77a1373b475" + integrity sha512-pxjw28CThdrqfz06nJkpAc5SXM404TXB/h5f4UJX+rrXJKE/1bu/KAILc2AY+O6cQIFtRjV9qOR2vaEp9LDGUA== case-sensitive-paths-webpack-plugin@^2.3.0: version "2.3.0" @@ -4521,15 +4603,20 @@ data-urls@^1.1.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" +dataloader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f" + integrity sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ== + date-fns@^1.27.2: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== date-fns@^2.16.0: - version "2.16.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.16.0.tgz#d34f0f5f2fd498c984513042e8f7247ea86c4cb7" - integrity sha512-DWTRyfOA85sZ4IiXPHhiRIOs3fW5U6Msrp+gElXARa6EpoQTXPyHQmh7hr+ssw2nx9FtOQWnAMJKgL5vaJqILw== + version "2.16.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.16.1.tgz#05775792c3f3331da812af253e1a935851d3834b" + integrity sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ== de-indent@^1.0.2: version "1.0.2" @@ -4993,9 +5080,9 @@ ejs@^2.6.1: integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== electron-to-chromium@^1.3.103, electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.523: - version "1.3.555" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.555.tgz#a096716ff77cf8da9a608eb628fd6927869503d2" - integrity sha512-/55x3nF2feXFZ5tdGUOr00TxnUjUgdxhrn+eCJ1FAcoAt+cKQTjQkUC5XF4frMWE1R5sjHk+JueuBalimfe5Pg== + version "1.3.557" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.557.tgz#00cafeed4397a6a9d1036911e434bc7404dc5e7c" + integrity sha512-M2p3nWulBqSEIisykYUVYnaSuRikHvxv8Wf209/Vg/sjrOew12hBQv2JvNGy+i+eDeJU9uQ3dbUbCCQ/CkudEg== elegant-spinner@^1.0.1: version "1.0.1" @@ -5369,6 +5456,11 @@ eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + eslint@^6.8.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" @@ -5413,11 +5505,12 @@ eslint@^6.8.0: v8-compile-cache "^2.0.3" eslint@^7.7.0: - version "7.7.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.7.0.tgz#18beba51411927c4b64da0a8ceadefe4030d6073" - integrity sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg== + version "7.8.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.8.1.tgz#e59de3573fb6a5be8ff526c791571646d124a8fa" + integrity sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w== dependencies: "@babel/code-frame" "^7.0.0" + "@eslint/eslintrc" "^0.1.3" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -5427,7 +5520,7 @@ eslint@^7.7.0: eslint-scope "^5.1.0" eslint-utils "^2.1.0" eslint-visitor-keys "^1.3.0" - espree "^7.2.0" + espree "^7.3.0" esquery "^1.2.0" esutils "^2.0.2" file-entry-cache "^5.0.1" @@ -5468,7 +5561,7 @@ espree@^6.1.2, espree@^6.2.1: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" -espree@^7.2.0: +espree@^7.3.0: version "7.3.0" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== @@ -5495,18 +5588,18 @@ esquery@^1.0.1, esquery@^1.2.0: estraverse "^5.1.0" esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0: +estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== @@ -6518,7 +6611,7 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -globby@11.0.1: +globby@11.0.1, globby@^11.0.1: version "11.0.1" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== @@ -7139,7 +7232,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.1.0: +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== @@ -9202,7 +9295,7 @@ mz@^2.4.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.12.1, nan@^2.13.2, nan@^2.14.0: +nan@^2.12.1, nan@^2.13.2: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== @@ -9301,6 +9394,11 @@ node-forge@0.9.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== +node-gyp-build@~3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" + integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== + node-gyp@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" @@ -10348,9 +10446,9 @@ posix-character-classes@^0.1.0: integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= postcss-calc@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.3.tgz#d65cca92a3c52bf27ad37a5f732e0587b74f1623" - integrity sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA== + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.4.tgz#5e177ddb417341e6d4a193c5d9fd8ada79094f8b" + integrity sha512-0I79VRAd1UTkaHzY9w83P39YGO/M3bG7/tNLrHGEunBolfoGM0hSjrGvjoeaj0JE/zIw5GsI2KZ0UwDJqv5hjw== dependencies: postcss "^7.0.27" postcss-selector-parser "^6.0.2" @@ -12621,7 +12719,7 @@ source-map@^0.4.2: dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -13008,7 +13106,7 @@ strip-json-comments@2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -strip-json-comments@^3.0.1, strip-json-comments@^3.1.0: +strip-json-comments@^3.0.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -13355,9 +13453,9 @@ tiptap-commands@^1.14.6: tiptap-utils "^1.10.4" tiptap-extensions@^1.29.1: - version "1.32.5" - resolved "https://registry.yarnpkg.com/tiptap-extensions/-/tiptap-extensions-1.32.5.tgz#3fdb6c7453e82262cfd22e2c1e32008b62978a26" - integrity sha512-lP1GQaPYfdgLAGI7+ss8zzBjdCIbNSmuBtdv6um6ML/rVMvXBEkNu2/a3k0CTtP6fIXCmUBV/PmCPAk21kOFhA== + version "1.32.6" + resolved "https://registry.yarnpkg.com/tiptap-extensions/-/tiptap-extensions-1.32.6.tgz#360de3d1ccc5c80be21cf207e60e5cfd82234622" + integrity sha512-6gN4QzrdYXqrfHi9581nxMWPo7rsvLIqF5z+lwqPg31sGuw27cffISf6akHP11OY7Ot9vOasgOxsHYlaxtZ4Zg== dependencies: lowlight "^1.14.0" prosemirror-collab "^1.2.2" @@ -13370,6 +13468,7 @@ tiptap-extensions@^1.29.1: prosemirror-view "^1.15.4" tiptap "^1.29.6" tiptap-commands "^1.14.6" + tiptap-utils "^1.10.4" tiptap-utils@^1.10.4: version "1.10.4" @@ -13989,6 +14088,13 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +utf-8-validate@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.2.tgz#63cfbccd85dc1f2b66cf7a1d0eebc08ed056bfb3" + integrity sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw== + dependencies: + node-gyp-build "~3.7.0" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -14611,15 +14717,16 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -websocket@1.0.31: - version "1.0.31" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.31.tgz#e5d0f16c3340ed87670e489ecae6144c79358730" - integrity sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ== +websocket@1.0.32: + version "1.0.32" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" + integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== dependencies: + bufferutil "^4.0.1" debug "^2.2.0" es5-ext "^0.10.50" - nan "^2.14.0" typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" yaeti "^0.0.6" whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: diff --git a/lib/federation/activity_pub/activity_pub.ex b/lib/federation/activity_pub/activity_pub.ex index e7b985ac0..81a8108c0 100644 --- a/lib/federation/activity_pub/activity_pub.ex +++ b/lib/federation/activity_pub/activity_pub.ex @@ -51,6 +51,8 @@ defmodule Mobilizon.Federation.ActivityPub do require Logger + @public_ap_adress "https://www.w3.org/ns/activitystreams#Public" + @doc """ Wraps an object into an activity """ @@ -111,10 +113,18 @@ defmodule Mobilizon.Federation.ActivityPub do {:ok, entity} end - with {:ok, entity} <- res do - Logger.debug("Going to preload an existing entity") + Logger.debug("Going to preload an existing entity") - Preloader.maybe_preload(entity) + case res do + {:ok, entity} -> + Preloader.maybe_preload(entity) + + {:error, status, entity} -> + {:ok, entity} = Preloader.maybe_preload(entity) + {:error, status, entity} + + err -> + err end e -> @@ -303,7 +313,8 @@ defmodule Mobilizon.Federation.ActivityPub do Make an actor follow another """ def follow(%Actor{} = follower, %Actor{} = followed, activity_id \\ nil, local \\ true) do - with {:ok, %Follower{} = follower} <- + with {:different_actors, true} <- {:different_actors, followed.id != follower.id}, + {:ok, %Follower{} = follower} <- Actors.follow(followed, follower, activity_id, false), follower_as_data <- Convertible.model_to_as(follower), {:ok, activity} <- create_activity(follower_as_data, local), @@ -312,6 +323,9 @@ defmodule Mobilizon.Federation.ActivityPub do else {:error, err, msg} when err in [:already_following, :suspended] -> {:error, msg} + + {:different_actors, _} -> + {:error, "Can't follow yourself"} end end @@ -649,7 +663,7 @@ defmodule Mobilizon.Federation.ActivityPub do defp convert_followers_in_recipients(recipients) do Enum.reduce(recipients, {recipients, []}, fn recipient, {recipients, follower_actors} = acc -> - case Actors.get_group_by_followers_url(recipient) do + case Actors.get_actor_by_followers_url(recipient) do %Actor{} = group -> {Enum.filter(recipients, fn recipient -> recipient != group.followers_url end), follower_actors ++ Actors.list_external_followers_for_actor(group)} @@ -797,9 +811,9 @@ defmodule Mobilizon.Federation.ActivityPub do @spec event_to_activity(%Event{}, boolean()) :: Activity.t() defp event_to_activity(%Event{} = event, local \\ true) do %Activity{ - recipients: ["https://www.w3.org/ns/activitystreams#Public"], + recipients: [@public_ap_adress], actor: event.organizer_actor.url, - data: Converter.Event.model_to_as(event), + data: event |> Convertible.model_to_as() |> make_create_data(%{"to" => @public_ap_adress}), local: local } end @@ -808,9 +822,10 @@ defmodule Mobilizon.Federation.ActivityPub do @spec comment_to_activity(%Comment{}, boolean()) :: Activity.t() defp comment_to_activity(%Comment{} = comment, local \\ true) do %Activity{ - recipients: ["https://www.w3.org/ns/activitystreams#Public"], + recipients: [@public_ap_adress], actor: comment.actor.url, - data: Converter.Comment.model_to_as(comment), + data: + comment |> Convertible.model_to_as() |> make_create_data(%{"to" => @public_ap_adress}), local: local } end diff --git a/lib/federation/activity_pub/fetcher.ex b/lib/federation/activity_pub/fetcher.ex index 6b6f859af..97ff31fd9 100644 --- a/lib/federation/activity_pub/fetcher.ex +++ b/lib/federation/activity_pub/fetcher.ex @@ -29,6 +29,7 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do {:ok, data} else {:ok, %Tesla.Env{status: 410}} -> + Logger.warn("Resource at #{url} is 410 Gone") {:error, "Gone"} {:ok, %Tesla.Env{} = res} -> diff --git a/lib/federation/activity_pub/refresher.ex b/lib/federation/activity_pub/refresher.ex index 3e4de5fd4..d825199da 100644 --- a/lib/federation/activity_pub/refresher.ex +++ b/lib/federation/activity_pub/refresher.ex @@ -6,9 +6,13 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do alias Mobilizon.Actors alias Mobilizon.Actors.Actor alias Mobilizon.Federation.ActivityPub - alias Mobilizon.Federation.ActivityPub.{Fetcher, Relay, Transmogrifier} + alias Mobilizon.Federation.ActivityPub.{Fetcher, Relay, Transmogrifier, Utils} require Logger + @doc """ + Refresh a remote profile + """ + @spec refresh_profile(Actor.t()) :: {:ok, Actor.t()} def refresh_profile(%Actor{domain: nil}), do: {:error, "Can only refresh remote actors"} def refresh_profile(%Actor{type: :Group, url: url, id: group_id} = group) do @@ -26,8 +30,11 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do end end - def refresh_profile(%Actor{type: :Person, url: url}) do - ActivityPub.make_actor_from_url(url) + def refresh_profile(%Actor{type: type, url: url}) when type in [:Person, :Application] do + with {:ok, %Actor{outbox_url: outbox_url}} <- ActivityPub.make_actor_from_url(url), + :ok <- fetch_collection(outbox_url, Relay.get_actor()) do + :ok + end end @spec fetch_group(String.t(), Actor.t()) :: :ok @@ -112,22 +119,13 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do defp process_collection(_, _), do: :error defp handling_element(data) when is_map(data) do - id = Map.get(data, "id") + object = get_in(data, ["object"]) - if id do - Mobilizon.Tombstone.delete_uri_tombstone(id) + if object do + object |> Utils.get_url() |> Mobilizon.Tombstone.delete_uri_tombstone() end - activity = %{ - "type" => "Create", - "to" => data["to"], - "cc" => data["cc"], - "actor" => data["actor"], - "attributedTo" => data["attributedTo"], - "object" => data - } - - Transmogrifier.handle_incoming(activity) + Transmogrifier.handle_incoming(data) end defp handling_element(uri) when is_binary(uri) do diff --git a/lib/federation/activity_pub/relay.ex b/lib/federation/activity_pub/relay.ex index 60741c2bf..0fd5b83d4 100644 --- a/lib/federation/activity_pub/relay.ex +++ b/lib/federation/activity_pub/relay.ex @@ -42,6 +42,10 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do Logger.info("Relay: followed instance #{target_instance}; id=#{activity.data["id"]}") {:ok, activity, follow} else + {:error, e} -> + Logger.warn("Error while following remote instance: #{inspect(e)}") + {:error, e} + e -> Logger.warn("Error while following remote instance: #{inspect(e)}") {:error, e} diff --git a/lib/federation/activity_pub/transmogrifier.ex b/lib/federation/activity_pub/transmogrifier.ex index 5c4a39e0b..fb0830890 100644 --- a/lib/federation/activity_pub/transmogrifier.ex +++ b/lib/federation/activity_pub/transmogrifier.ex @@ -17,7 +17,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do alias Mobilizon.Todos.{Todo, TodoList} alias Mobilizon.Federation.ActivityPub - alias Mobilizon.Federation.ActivityPub.{Activity, Relay, Utils} + alias Mobilizon.Federation.ActivityPub.{Activity, Refresher, Relay, Utils} alias Mobilizon.Federation.ActivityPub.Types.Ownable alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Tombstone @@ -656,7 +656,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do Handle incoming `Accept` activities wrapping a `Follow` activity """ def do_handle_incoming_accept_following(follow_object, %Actor{} = actor) do - with {:follow, {:ok, %Follower{approved: false, target_actor: followed} = follow}} <- + with {:follow, + {:ok, %Follower{approved: false, target_actor: followed, actor: follower} = follow}} <- {:follow, get_follow(follow_object)}, {:same_actor, true} <- {:same_actor, actor.id == followed.id}, {:ok, %Activity{} = activity, %Follower{approved: true} = follow} <- @@ -665,6 +666,13 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do follow, false ) do + relay_actor = Relay.get_actor() + + # If this is an instance follow, refresh the followed profile (especially their outbox) + if follower.id == relay_actor.id do + Refresher.refresh_profile(followed) + end + {:ok, activity, follow} else {:follow, _} -> diff --git a/lib/federation/activity_stream/converter/event.ex b/lib/federation/activity_stream/converter/event.ex index 04dff326b..0f4f94c4d 100644 --- a/lib/federation/activity_stream/converter/event.ex +++ b/lib/federation/activity_stream/converter/event.ex @@ -107,15 +107,19 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do do: ["https://www.w3.org/ns/activitystreams#Public"], else: [event.organizer_actor.followers_url] - res = %{ + %{ "type" => "Event", "to" => to, "cc" => [], "attributedTo" => - if(is_nil(event.attributed_to), do: nil, else: event.attributed_to.url) || + if(is_nil(event.attributed_to) or not Ecto.assoc_loaded?(event.attributed_to), + do: nil, + else: event.attributed_to.url + ) || event.organizer_actor.url, "name" => event.title, - "actor" => event.organizer_actor.url, + "actor" => + if(Ecto.assoc_loaded?(event.organizer_actor), do: event.organizer_actor.url, else: nil), "uuid" => event.uuid, "category" => event.category, "content" => event.description, @@ -136,40 +140,9 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do "id" => event.url, "url" => event.url } - - res = - if is_nil(event.physical_address), - do: res, - else: Map.put(res, "location", AddressConverter.model_to_as(event.physical_address)) - - res = - if is_nil(event.picture), - do: res, - else: - Map.update( - res, - "attachment", - [], - &(&1 ++ [PictureConverter.model_to_as(event.picture)]) - ) - - if is_nil(event.online_address), - do: res, - else: - Map.update( - res, - "attachment", - [], - &(&1 ++ - [ - %{ - "type" => "Link", - "href" => event.online_address, - "mediaType" => "text/html", - "name" => "Website" - } - ]) - ) + |> maybe_add_physical_address(event) + |> maybe_add_event_picture(event) + |> maybe_add_online_address(event) end # Get only elements that we have in EventOptions @@ -249,4 +222,45 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do end end) end + + @spec maybe_add_physical_address(map(), Event.t()) :: map() + defp maybe_add_physical_address(res, event) do + if is_nil(event.physical_address), + do: res, + else: Map.put(res, "location", AddressConverter.model_to_as(event.physical_address)) + end + + @spec maybe_add_event_picture(map(), Event.t()) :: map() + defp maybe_add_event_picture(res, event) do + if is_nil(event.picture), + do: res, + else: + Map.update( + res, + "attachment", + [], + &(&1 ++ [PictureConverter.model_to_as(event.picture)]) + ) + end + + @spec maybe_add_online_address(map(), Event.t()) :: map() + defp maybe_add_online_address(res, event) do + if is_nil(event.online_address), + do: res, + else: + Map.update( + res, + "attachment", + [], + &(&1 ++ + [ + %{ + "type" => "Link", + "href" => event.online_address, + "mediaType" => "text/html", + "name" => "Website" + } + ]) + ) + end end diff --git a/lib/graphql/api/follows.ex b/lib/graphql/api/follows.ex index 11b0eef7d..b47cb75f1 100644 --- a/lib/graphql/api/follows.ex +++ b/lib/graphql/api/follows.ex @@ -16,6 +16,10 @@ defmodule Mobilizon.GraphQL.API.Follows do {:ok, activity, follow} -> {:ok, activity, follow} + {:error, e} -> + Logger.warn("Error while following actor: #{inspect(e)}") + {:error, e} + e -> Logger.warn("Error while following actor: #{inspect(e)}") {:error, e} diff --git a/lib/graphql/resolvers/admin.ex b/lib/graphql/resolvers/admin.ex index 90ef50f0b..80b771713 100644 --- a/lib/graphql/resolvers/admin.ex +++ b/lib/graphql/resolvers/admin.ex @@ -249,7 +249,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do {:ok, _activity, follow} -> {:ok, follow} - {:error, {:error, err}} when is_bitstring(err) -> + {:error, err} when is_binary(err) -> {:error, err} end end diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 3dc37df7f..0584d364c 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -561,9 +561,9 @@ defmodule Mobilizon.Actors do |> Repo.one() end - @spec get_group_by_followers_url(String.t()) :: Actor.t() - def get_group_by_followers_url(followers_url) do - group_query() + @spec get_actor_by_followers_url(String.t()) :: Actor.t() + def get_actor_by_followers_url(followers_url) do + Actor |> where([q], q.followers_url == ^followers_url) |> Repo.one() end diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index a6f27cb52..7fd6e996c 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -251,8 +251,9 @@ defmodule Mobilizon.Events do def create_event(attrs \\ %{}) do with {:ok, %{insert: %Event{} = event}} <- do_create_event(attrs), %Event{} = event <- Repo.preload(event, @event_preloads) do - unless event.draft, - do: Workers.BuildSearch.enqueue(:insert_search_event, %{"event_id" => event.id}) + unless event.draft do + Workers.BuildSearch.enqueue(:insert_search_event, %{"event_id" => event.id}) + end {:ok, event} else diff --git a/lib/mobilizon/tombstone.ex b/lib/mobilizon/tombstone.ex index 85e8ff9a5..7b464b6c7 100644 --- a/lib/mobilizon/tombstone.ex +++ b/lib/mobilizon/tombstone.ex @@ -41,7 +41,10 @@ defmodule Mobilizon.Tombstone do @spec find_tombstone(String.t()) :: Ecto.Schema.t() | nil def find_tombstone(uri) do - Repo.get_by(__MODULE__, uri: uri) + __MODULE__ + |> Ecto.Query.where([t], t.uri == ^uri) + |> Ecto.Query.preload([t], [:actor]) + |> Repo.one() end @spec delete_actor_tombstones(String.t() | integer()) :: {integer(), nil} diff --git a/lib/service/formatter/html.ex b/lib/service/formatter/html.ex index 96780267d..926d3fee2 100644 --- a/lib/service/formatter/html.ex +++ b/lib/service/formatter/html.ex @@ -30,11 +30,13 @@ defmodule Mobilizon.Service.Formatter.HTML do `

test

next` thing becomes `test next` instead of `testnext` """ @spec strip_tags_and_insert_spaces(String.t()) :: String.t() - def strip_tags_and_insert_spaces(html) do + def strip_tags_and_insert_spaces(html) when is_binary(html) do html |> String.replace(" strip_tags() end + def strip_tags_and_insert_spaces(html), do: html + def filter_tags_for_oembed(html), do: Sanitizer.scrub(html, OEmbed) end diff --git a/lib/service/workers/helper.ex b/lib/service/workers/helper.ex index ee50e59af..53232563e 100644 --- a/lib/service/workers/helper.ex +++ b/lib/service/workers/helper.ex @@ -37,6 +37,8 @@ defmodule Mobilizon.Service.Workers.Helper do queue: unquote(queue), max_attempts: 1 + alias Oban.Job + def enqueue(operation, params, worker_args \\ []) do params = Map.merge(%{"op" => operation}, params) queue_atom = String.to_existing_atom(unquote(queue)) diff --git a/lib/web/views/activity_pub/actor_view.ex b/lib/web/views/activity_pub/actor_view.ex index 23f9913f9..7b2ab9b35 100644 --- a/lib/web/views/activity_pub/actor_view.ex +++ b/lib/web/views/activity_pub/actor_view.ex @@ -160,7 +160,7 @@ defmodule Mobilizon.Web.ActivityPub.ActorView do map end - def item(%Activity{data: %{"id" => id}}), do: id + def item(%Activity{data: data}), do: data def item(%Actor{url: url}), do: url def item(%Member{} = member), do: Convertible.model_to_as(member) def item(%Resource{} = resource), do: Convertible.model_to_as(resource) diff --git a/mix.lock b/mix.lock index c79deffdb..5d5beec4f 100644 --- a/mix.lock +++ b/mix.lock @@ -35,11 +35,11 @@ "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "esaml": {:git, "git://github.com/wrren/esaml.git", "2cace5778e4323216bcff2085ca9739e42a68a42", [branch: "ueberauth_saml"]}, "eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm", "b14f1dc204321429479c569cfbe8fb287541184ed040956c8862cb7a677b8406"}, - "ex_cldr": {:hex, :ex_cldr, "2.16.1", "905b03c38b5fb51668a347f2e6b586bcb2c0816cd98f7d913104872c43cbc61f", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.9", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "006e500769982e57e6f3e32cbc4664345f78b014bb5ff48ddc394d67c86c1a8d"}, - "ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.9.0", "ace1c57ba3850753c9ac6ddb89dc0c9a9e5e1c57ecad587e21c8925ad30a3838", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.13", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.0", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "a4b07773e2a326474f44a6bc51fffbec634859a1bad5cc6e6eb55eba45115541"}, - "ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.6.1", "accc6b409c88c3ce4d9439f0a92e375470b788efa95d8fa5a054aa9e8950e972", [:mix], [{:ex_cldr, "~> 2.14", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "ca9817eadc78f11f1084f64c579288513b0042eaa39ea2337d68ba959ebae1ad"}, + "ex_cldr": {:hex, :ex_cldr, "2.16.2", "75e344eaeae7c6943cce84220efd45d52e84f907400234f11d2cf0471d00080a", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.9", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "04d71af6248d34207eeb4d1b6628848b18e9dbb7c05411d956e930b4a186c746"}, + "ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.10.0", "733d8bbc1fa4e5c1836cda0733664e17cf1aa6a75d407786c03cc8c3a26a6a82", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.13", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.0", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "a9842b8f3052e28f155a019e791f177f50d0da54cc41869f70d111ea907c9969"}, + "ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.6.2", "b7e9e0075d0e90faae24ee2cb1c7eb5b53e547f2d8a5445a78ebc284c4ea5f83", [:mix], [{:ex_cldr, "~> 2.14", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "89dd1913ca3d95c27579564a2abec3fa45b6847a304ffaac6a16f960615cb798"}, "ex_cldr_dates_times": {:hex, :ex_cldr_dates_times, "2.5.1", "9439d1c40cfd03c3d8f3f60f5d3e3f2c6eaf0fd714541d687531cce78cfb9909", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_calendars, "~> 1.8", [hex: :ex_cldr_calendars, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.15", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "62a2f8d41ec6e789137bbf3ac7c944885a8ef6b7ce475905d056d1805b482427"}, - "ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.15.1", "dced7ffee69c4830593258b69b294adb4c65cf539e1d8ae0a4de31cfc8aa56a0", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.15", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.5", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "c6a4b69ef80b8ffbb6c8fb69a2b365ba542580e0f76a15d8c6ee9142bd1b97ea"}, + "ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.15.2", "5023b2a807117e51faa28c18f75ac976c11a9c75e9278641529079ecdc982684", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.15", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.5", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "6519e22f01d17bdef72dba92ea61f39ce90ee1e57f87a004bb088f99716e391a"}, "ex_crypto": {:hex, :ex_crypto, "0.10.0", "af600a89b784b36613a989da6e998c1b200ff1214c3cfbaf8deca4aa2f0a1739", [:mix], [{:poison, ">= 2.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "ccc7472cfe8a0f4565f97dce7e9280119bf15a5ea51c6535e5b65f00660cde1c"}, "ex_doc": {:hex, :ex_doc, "0.22.2", "03a2a58bdd2ba0d83d004507c4ee113b9c521956938298eba16e55cc4aba4a6c", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "cf60e1b3e2efe317095b6bb79651f83a2c1b3edcb4d319c421d7fcda8b3aff26"}, "ex_ical": {:hex, :ex_ical, "0.2.0", "4b928b554614704016cc0c9ee226eb854da9327a1cc460457621ceacb1ac29a6", [:mix], [{:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "db76473b2ae0259e6633c6c479a5a4d8603f09497f55c88f9ef4d53d2b75befb"}, @@ -51,8 +51,8 @@ "exgravatar": {:hex, :exgravatar, "2.0.2", "638412896170409da114f98947d3f8d4f38e851b0e329c1cc4cd324d5e2ea081", [:mix], [], "hexpm", "f3deb5baa6fcf354a965d794ee73a956d95f1f79f41bddf69800c713cfb014a1"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, "exvcr": {:hex, :exvcr, "0.11.2", "24aec6ad13a659f10591911089c01f8d2691e2fff75710c924b64437cc1b36a1", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "0dad8a3065af4040933bc3ec296f28654b04e993a81054199c832fa86329e80f"}, - "fast_html": {:hex, :fast_html, "2.0.2", "1fabc408b2baa965cf6399a48796326f2721b21b397a3c667bb3bb88fb9559a4", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "f077e2c1597a6e2678e6cacc64f456a6c6024eb4240092c46d4212496dc59aba"}, - "fast_sanitize": {:hex, :fast_sanitize, "0.2.1", "3302421a988992b6cae08e68f77069e167ff116444183f3302e3c36017a50558", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bcd2c54e328128515edd1a8fb032fdea7e5581672ba161fc5962d21ecee92502"}, + "fast_html": {:hex, :fast_html, "2.0.4", "4910ee49f2f6b19692e3bf30bf97f1b6b7dac489cd6b0f34cd0fe3042c56ba30", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "3bb49d541dfc02ad5e425904f53376d758c09f89e521afc7d2b174b3227761ea"}, + "fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"}, "file_info": {:hex, :file_info, "0.0.4", "2e0e77f211e833f38ead22cb29ce53761d457d80b3ffe0ffe0eb93880b0963b2", [:mix], [{:mimetype_parser, "~> 0.1.2", [hex: :mimetype_parser, repo: "hexpm", optional: false]}], "hexpm", "50e7ad01c2c8b9339010675fe4dc4a113b8d6ca7eddce24d1d74fd0e762781a5"}, "file_system": {:hex, :file_system, "0.2.8", "f632bd287927a1eed2b718f22af727c5aeaccc9a98d8c2bd7bff709e851dc986", [:mix], [], "hexpm", "97a3b6f8d63ef53bd0113070102db2ce05352ecf0d25390eb8d747c2bde98bca"}, "floki": {:hex, :floki, "0.28.0", "0d0795a17189510ee01323e6990f906309e9fc6e8570219135211f1264d78c7f", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "db1549560874ebba5a6367e46c3aec5fedd41f2757ad6efe567efb04b4d4ee55"}, @@ -105,7 +105,7 @@ "paddle": {:hex, :paddle, "0.1.4", "3697996d79e3d771d6f7560a23e4bad1ed7b7f7fd3e784f97bc39565963b2b13", [:mix], [], "hexpm", "fc719a9e7c86f319b9f4bf413d6f0f326b0c4930d5bc6630d074598ed38e2143"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, "phoenix": {:hex, :phoenix, "1.5.4", "0fca9ce7e960f9498d6315e41fcd0c80bfa6fbeb5fa3255b830c67fdfb7e703f", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4e516d131fde87b568abd62e1b14aa07ba7d5edfd230bab4e25cc9dedbb39135"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "4.1.0", "a044d0756d0464c5a541b4a0bf4bcaf89bffcaf92468862408290682c73ae50d", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c5e666a341ff104d0399d8f0e4ff094559b2fde13a5985d4cb5023b2c2ac558b"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "4.2.0", "4ac3300a22240a37ed54dfe6c0be1b5623304385d1a2c210a70f011d9e7af7ac", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "59e7e2a550d7ea082a665c0fc29485f06f55d1a51dd02f513aafdb9d16fc72c4"}, "phoenix_html": {:hex, :phoenix_html, "2.14.2", "b8a3899a72050f3f48a36430da507dd99caf0ac2d06c77529b1646964f3d563e", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "58061c8dfd25da5df1ea0ca47c972f161beb6c875cd293917045b92ffe1bf617"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.4", "940c0344b1d66a2e46eef02af3a70e0c5bb45a4db0bf47917add271b76cd3914", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "38f9308357dea4cc77f247e216da99fcb0224e05ada1469167520bed4cb8cccd"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"}, diff --git a/priv/repo/migrations/20200901101307_fix_relay_visibility.exs b/priv/repo/migrations/20200901101307_fix_relay_visibility.exs new file mode 100644 index 000000000..1a5d1aa5a --- /dev/null +++ b/priv/repo/migrations/20200901101307_fix_relay_visibility.exs @@ -0,0 +1,19 @@ +defmodule Mobilizon.Storage.Repo.Migrations.FixRelayVisibility do + use Ecto.Migration + alias Mobilizon.Actors.Actor + alias Mobilizon.Storage.Repo + import Ecto.Query + + def up do + Actor + |> where(preferred_username: "relay") + |> where(type: "Application") + |> where([a], is_nil(a.domain)) + |> update(set: [visibility: "public"]) + |> Repo.update_all([]) + end + + def down do + IO.puts("Not changing Relay visibility back") + end +end diff --git a/test/federation/activity_pub/transmogrifier_test.exs b/test/federation/activity_pub/transmogrifier_test.exs index 4d3e7d995..cfee647c7 100644 --- a/test/federation/activity_pub/transmogrifier_test.exs +++ b/test/federation/activity_pub/transmogrifier_test.exs @@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney use Mobilizon.DataCase + use Oban.Testing, repo: Mobilizon.Storage.Repo import Mobilizon.Factory import ExUnit.CaptureLog @@ -738,7 +739,16 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do use_cassette "activity_pub/event_update_activities" do data = File.read!("test/fixtures/mobilizon-post-activity.json") |> Jason.decode!() - {:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data) + {:ok, %Activity{data: data, local: false}, %Event{id: event_id}} = + Transmogrifier.handle_incoming(data) + + assert_enqueued( + worker: Mobilizon.Service.Workers.BuildSearch, + args: %{event_id: event_id, op: :insert_search_event} + ) + + assert %{success: 1, failure: 0} == Oban.drain_queue(queue: :search) + update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!() object = @@ -757,6 +767,14 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do Transmogrifier.handle_incoming(update_data) %Event{} = event = Events.get_event_by_url(data["object"]["id"]) + + assert_enqueued( + worker: Mobilizon.Service.Workers.BuildSearch, + args: %{event_id: event_id, op: :update_search_event} + ) + + assert %{success: 1, failure: 0} == Oban.drain_queue(queue: :search) + assert event.title == "My updated event" assert event.description == data["object"]["content"] diff --git a/test/web/controllers/activity_pub_controller_test.exs b/test/web/controllers/activity_pub_controller_test.exs index c5548a52b..a400d4905 100644 --- a/test/web/controllers/activity_pub_controller_test.exs +++ b/test/web/controllers/activity_pub_controller_test.exs @@ -143,8 +143,10 @@ defmodule Mobilizon.Web.ActivityPubControllerTest do conn |> get(Actor.build_url(actor.preferred_username, :outbox)) - assert json_response(conn, 200)["totalItems"] == 1 - assert json_response(conn, 200)["first"]["orderedItems"] == [comment.url] + assert res = json_response(conn, 200) + + assert res["totalItems"] == 1 + assert res["first"]["orderedItems"] |> Enum.map(& &1["object"]["id"]) == [comment.url] end test "it returns an event activity in a collection", %{conn: conn} do @@ -155,8 +157,10 @@ defmodule Mobilizon.Web.ActivityPubControllerTest do conn |> get(Actor.build_url(actor.preferred_username, :outbox)) - assert json_response(conn, 200)["totalItems"] == 1 - assert json_response(conn, 200)["first"]["orderedItems"] == [event.url] + assert res = json_response(conn, 200) + + assert res["totalItems"] == 1 + assert res["first"]["orderedItems"] |> Enum.map(& &1["object"]["id"]) == [event.url] end test "it works for more than 10 events", %{conn: conn} do From 7a4d526e459ca8cd3e325e3019e1e665893b5238 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 2 Sep 2020 09:24:22 +0200 Subject: [PATCH 3/4] Add a noindex HTTP header on unlisted resources Signed-off-by: Thomas Citharel --- lib/web/controllers/page_controller.ex | 17 ++++++++++++++++- test/web/controllers/page_controller_test.exs | 9 ++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/web/controllers/page_controller.ex b/lib/web/controllers/page_controller.ex index f2a8e66c9..6c026a220 100644 --- a/lib/web/controllers/page_controller.ex +++ b/lib/web/controllers/page_controller.ex @@ -7,6 +7,7 @@ defmodule Mobilizon.Web.PageController do alias Mobilizon.Discussions.Comment alias Mobilizon.Events.Event alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Posts.Post alias Mobilizon.Tombstone alias Mobilizon.Web.{ActivityPubController, Cache, PageController} @@ -122,7 +123,9 @@ defmodule Mobilizon.Web.PageController do |> render(object_type, object: object) _ -> - render(conn, object_type, object: object) + conn + |> maybe_add_noindex_header(object) + |> render(object_type, object: object) end :remote -> @@ -153,4 +156,16 @@ defmodule Mobilizon.Web.PageController do defp is_local?(%{local: local}), do: if(local, do: true, else: :remote) defp is_local?(_), do: false + + defp maybe_add_noindex_header(conn, %Event{visibility: visibility}) + when visibility != :public do + put_resp_header(conn, "x-robots-tag", "noindex") + end + + defp maybe_add_noindex_header(conn, %Post{visibility: visibility}) + when visibility != :public do + put_resp_header(conn, "x-robots-tag", "noindex") + end + + defp maybe_add_noindex_header(conn, _), do: conn end diff --git a/test/web/controllers/page_controller_test.exs b/test/web/controllers/page_controller_test.exs index c0f81bc7f..7d67b5489 100644 --- a/test/web/controllers/page_controller_test.exs +++ b/test/web/controllers/page_controller_test.exs @@ -30,11 +30,18 @@ defmodule Mobilizon.Web.PageControllerTest do end test "GET /events/:uuid", %{conn: conn} do - event = insert(:event) + event = insert(:event, visibility: :public) conn = get(conn, Routes.page_url(Endpoint, :event, event.uuid)) assert html_response(conn, 200) =~ event.title end + test "GET /events/:uuid with unlisted event", %{conn: conn} do + event = insert(:event, visibility: :unlisted) + conn = get(conn, Routes.page_url(Endpoint, :event, event.uuid)) + assert html_response(conn, 200) =~ event.title + assert ["noindex"] == get_resp_header(conn, "x-robots-tag") + end + test "GET /events/:uuid with not existing event", %{conn: conn} do conn = get(conn, Routes.page_url(Endpoint, :event, "not_existing_event")) assert html_response(conn, 404) From 6e982bb9ce8909b7c313c6dd46bfea9640ec2888 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 2 Sep 2020 10:00:39 +0200 Subject: [PATCH 4/4] Show group address in group metadata Signed-off-by: Thomas Citharel --- js/src/i18n/en_US.json | 4 +-- js/src/i18n/fr_FR.json | 9 ++---- js/src/views/Group/GroupSettings.vue | 4 ++- lib/mobilizon/actors/actors.ex | 2 +- lib/service/metadata/actor.ex | 22 ++++++++++++++- lib/web/cache/activity_pub.ex | 2 +- lib/web/controllers/page_controller.ex | 7 +---- lib/web/views/json_ld/object_view.ex | 39 ++++++++++++++++++++------ 8 files changed, 61 insertions(+), 28 deletions(-) diff --git a/js/src/i18n/en_US.json b/js/src/i18n/en_US.json index fa34de2af..1ca564181 100644 --- a/js/src/i18n/en_US.json +++ b/js/src/i18n/en_US.json @@ -731,7 +731,6 @@ "any distance": "any distance", "Group visibility": "Group visibility", "The group will be publicly listed in search results and may be suggested in the explore section. Only public informations will be shown on it's page.": "The group will be publicly listed in search results and may be suggested in the explore section. Only public informations will be shown on it's page.", - "You'll need to transmit the group URL so people may access the group's profile.": "You'll need to transmit the group URL so people may access the group's profile.", "Group address": "Group address", "Events tagged with {tag}": "Events tagged with {tag}", "Explore events": "Explore events", @@ -793,5 +792,6 @@ "A place to publish something to the whole world, your community or just your group members.": "A place to publish something to the whole world, your community or just your group members.", "No posts found": "No posts found", "Last sign-in": "Last sign-in", - "Last IP adress": "Last IP adress" + "Last IP adress": "Last IP adress", + "You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines.": "You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines." } diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json index 28595f163..20e064ced 100644 --- a/js/src/i18n/fr_FR.json +++ b/js/src/i18n/fr_FR.json @@ -456,7 +456,6 @@ "Please refresh the page and retry.": "Merci de rafraîchir la page puis réessayer.", "Post": "Billet", "Post a comment": "Ajouter un commentaire", - "Post a public message": "Poster un message public", "Post a reply": "Envoyer une réponse", "Postal Code": "Code postal", "Posts": "Billets", @@ -634,10 +633,6 @@ "Username": "Pseudo", "Users": "Utilisateur⋅ice⋅s", "View a reply": "Aucune réponse | Voir une réponse | Voir {totalReplies} réponses", - "View all discussions": "Voir toutes les discussions", - "View all events": "Voir tous les événements", - "View all resources": "Voir toutes les resources", - "View all todos": "Voir tous les todos", "View all upcoming events": "Voir tous les événements à venir", "View event page": "Voir la page de l'évènement", "View everything": "Voir tout", @@ -684,7 +679,6 @@ "You will be redirected to the original instance": "Vous allez être redirigé⋅e vers l'instance d'origine", "You wish to participate to the following event": "Vous souhaitez participer à l'événement suivant", "You'll get a weekly recap every Monday for upcoming events, if you have any.": "Vous recevrez un récapitulatif hebdomadaire chaque lundi pour les événements de la semaine, si vous en avez.", - "You'll need to transmit the group URL so people may access the group's profile.": "Vous aurez besoin de transmettre l'URL du groupe pour que d'autres personnes accèdent au profil du groupe.", "You'll receive a confirmation email.": "Vous recevrez un email de confirmation.", "Your account has been successfully deleted": "Votre compte a été supprimé avec succès", "Your account has been validated": "Votre compte a été validé", @@ -798,5 +792,6 @@ "A place to publish something to the whole world, your community or just your group members.": "Un endroit pour publier quelque chose à l'intention du monde entier, de votre communauté ou simplement des membres de votre groupe.", "No posts found": "Aucun billet trouvé", "Last sign-in": "Dernière connexion", - "Last IP adress": "Dernière addresse IP" + "Last IP adress": "Dernière addresse IP", + "You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines.": "Vous aurez besoin de transmettre l'URL du groupe pour que d'autres personnes accèdent au profil du groupe. Le groupe ne sera pas trouvable dans la recherche de Mobilizon ni dans les moteurs de recherche habituels." } diff --git a/js/src/views/Group/GroupSettings.vue b/js/src/views/Group/GroupSettings.vue index 4d207e605..084557e43 100644 --- a/js/src/views/Group/GroupSettings.vue +++ b/js/src/views/Group/GroupSettings.vue @@ -61,7 +61,9 @@ :native-value="GroupVisibility.UNLISTED" >{{ $t("Only accessible through link") }}
{{ - $t("You'll need to transmit the group URL so people may access the group's profile.") + $t( + "You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines." + ) }}

diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 0584d364c..8e1e1a755 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -187,7 +187,7 @@ defmodule Mobilizon.Actors do def get_actor_by_name_with_preload(name, type \\ nil) do name |> get_actor_by_name(type) - |> Repo.preload([:organized_events, :user]) + |> Repo.preload([:organized_events, :user, :physical_address]) end @doc """ diff --git a/lib/service/metadata/actor.ex b/lib/service/metadata/actor.ex index 00b14415e..5677edf8e 100644 --- a/lib/service/metadata/actor.ex +++ b/lib/service/metadata/actor.ex @@ -1,10 +1,12 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do + alias Phoenix.HTML alias Phoenix.HTML.Tag alias Mobilizon.Actors.Actor + alias Mobilizon.Web.JsonLD.ObjectView alias Mobilizon.Web.MediaProxy def build_tags(%Actor{} = actor, _locale \\ "en") do - tags = [ + [ Tag.tag(:meta, property: "og:title", content: Actor.display_name_and_username(actor)), Tag.tag(:meta, property: "og:url", content: actor.url), Tag.tag(:meta, property: "og:description", content: actor.summary), @@ -12,7 +14,12 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do Tag.tag(:meta, property: "profile:username", content: actor.preferred_username), Tag.tag(:meta, property: "twitter:card", content: "summary") ] + |> maybe_add_avatar(actor) + |> maybe_add_group_schema(actor) + end + @spec maybe_add_avatar(list(Tag.t()), Actor.t()) :: list(Tag.t()) + defp maybe_add_avatar(tags, actor) do if is_nil(actor.avatar) do tags else @@ -20,4 +27,17 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do [Tag.tag(:meta, property: "og:image", content: actor.avatar.url |> MediaProxy.url())] end end + + defp maybe_add_group_schema(tags, %Actor{type: :Group} = group) do + tags ++ [~s{} |> HTML.raw()] + end + + defp maybe_add_group_schema(tags, _), do: tags + + # Insert JSON-LD schema by hand because Tag.content_tag wants to escape it + defp json(%Actor{} = group) do + "group.json" + |> ObjectView.render(%{group: group}) + |> Jason.encode!() + end end diff --git a/lib/web/cache/activity_pub.ex b/lib/web/cache/activity_pub.ex index bb9df1e41..f32cf598f 100644 --- a/lib/web/cache/activity_pub.ex +++ b/lib/web/cache/activity_pub.ex @@ -23,7 +23,7 @@ defmodule Mobilizon.Web.Cache.ActivityPub do {:commit, Actor.t()} | {:ignore, nil} def get_actor_by_name(name) do Cachex.fetch(@cache, "actor_" <> name, fn "actor_" <> name -> - case Actors.get_actor_by_name(name) do + case Actors.get_actor_by_name_with_preload(name) do %Actor{} = actor -> {:commit, actor} diff --git a/lib/web/controllers/page_controller.ex b/lib/web/controllers/page_controller.ex index 6c026a220..64bef0b88 100644 --- a/lib/web/controllers/page_controller.ex +++ b/lib/web/controllers/page_controller.ex @@ -157,12 +157,7 @@ defmodule Mobilizon.Web.PageController do defp is_local?(%{local: local}), do: if(local, do: true, else: :remote) defp is_local?(_), do: false - defp maybe_add_noindex_header(conn, %Event{visibility: visibility}) - when visibility != :public do - put_resp_header(conn, "x-robots-tag", "noindex") - end - - defp maybe_add_noindex_header(conn, %Post{visibility: visibility}) + defp maybe_add_noindex_header(conn, %{visibility: visibility}) when visibility != :public do put_resp_header(conn, "x-robots-tag", "noindex") end diff --git a/lib/web/views/json_ld/object_view.ex b/lib/web/views/json_ld/object_view.ex index 59e69976c..7db4a393f 100644 --- a/lib/web/views/json_ld/object_view.ex +++ b/lib/web/views/json_ld/object_view.ex @@ -8,6 +8,16 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do alias Mobilizon.Web.JsonLD.ObjectView alias Mobilizon.Web.MediaProxy + def render("group.json", %{group: %Actor{} = group}) do + %{ + "@context" => "http://schema.org", + "@type" => "Organization", + "url" => group.url, + "name" => group.name || group.preferred_username, + "address" => render_address(group) + } + end + def render("event.json", %{event: %Event{} = event}) do organizer = %{ "@type" => if(event.organizer_actor.type == :Group, do: "Organization", else: "Person"), @@ -56,14 +66,18 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do %{ "@type" => "Place", "name" => address.description, - "address" => %{ - "@type" => "PostalAddress", - "streetAddress" => address.street, - "addressLocality" => address.locality, - "postalCode" => address.postal_code, - "addressRegion" => address.region, - "addressCountry" => address.country - } + "address" => render_one(address, ObjectView, "address.json", as: :address) + } + end + + def render("address.json", %{address: %Address{} = address}) do + %{ + "@type" => "PostalAddress", + "streetAddress" => address.street, + "addressLocality" => address.locality, + "postalCode" => address.postal_code, + "addressRegion" => address.region, + "addressCountry" => address.country } end @@ -81,7 +95,7 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do } end - defp render_location(%Event{physical_address: %Address{} = address}), + defp render_location(%{physical_address: %Address{} = address}), do: render_one(address, ObjectView, "place.json", as: :address) # For now the Virtual Location of an event is it's own URL, @@ -92,4 +106,11 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do "url" => event_url } end + + defp render_location(_), do: nil + + defp render_address(%{physical_address: %Address{} = address}), + do: render_one(address, ObjectView, "address.json", as: :address) + + defp render_address(_), do: nil end