Merge remote-tracking branch 'origin/develop' into feature/embeddable-posts
authorEgor Kislitsyn <egor@kislitsyn.com>
Mon, 1 Jun 2020 13:38:57 +0000 (17:38 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Mon, 1 Jun 2020 13:38:57 +0000 (17:38 +0400)
1  2 
lib/pleroma/constants.ex
lib/pleroma/web/router.ex
lib/pleroma/web/templates/embed/show.html.eex
lib/pleroma/web/templates/layout/embed.html.eex
lib/pleroma/web/views/embed_view.ex

diff --combined lib/pleroma/constants.ex
index 4ba39b53faeef6baebb89788c599d26626325288,06174f624a6d4d80a1c457a74f5e888122a5b516..13eeaa96b4762fbb91ced797cd93c7ad2dcf9255
@@@ -17,7 -17,13 +17,13 @@@ defmodule Pleroma.Constants d
        "announcement_count",
        "emoji",
        "context_id",
-       "deleted_activity_id"
+       "deleted_activity_id",
+       "pleroma_internal"
      ]
    )
 -      ~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc)
+   const(static_only_files,
+     do:
++      ~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css)
+   )
  end
index eef0a80231e4bd6f2d9ca0aa3b3f97bcc1b9e9b3,e493a41534bb0f8b3a0a11e0eb6ec7714e4fd803..a2626521e1d8cc218226a2995ac854c09191ef66
@@@ -16,75 -16,70 +16,70 @@@ defmodule Pleroma.Web.Router d
      plug(Pleroma.Plugs.UserEnabledPlug)
    end
  
-   pipeline :api do
-     plug(:accepts, ["json"])
-     plug(:fetch_session)
+   pipeline :expect_authentication do
+     plug(Pleroma.Plugs.ExpectAuthenticatedCheckPlug)
+   end
+   pipeline :expect_public_instance_or_authentication do
+     plug(Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug)
+   end
+   pipeline :authenticate do
      plug(Pleroma.Plugs.OAuthPlug)
      plug(Pleroma.Plugs.BasicAuthDecoderPlug)
      plug(Pleroma.Plugs.UserFetcherPlug)
      plug(Pleroma.Plugs.SessionAuthenticationPlug)
      plug(Pleroma.Plugs.LegacyAuthenticationPlug)
      plug(Pleroma.Plugs.AuthenticationPlug)
+   end
+   pipeline :after_auth do
      plug(Pleroma.Plugs.UserEnabledPlug)
      plug(Pleroma.Plugs.SetUserSessionIdPlug)
      plug(Pleroma.Plugs.EnsureUserKeyPlug)
-     plug(Pleroma.Plugs.IdempotencyPlug)
    end
  
-   pipeline :authenticated_api do
+   pipeline :base_api do
      plug(:accepts, ["json"])
      plug(:fetch_session)
-     plug(Pleroma.Plugs.OAuthPlug)
-     plug(Pleroma.Plugs.BasicAuthDecoderPlug)
-     plug(Pleroma.Plugs.UserFetcherPlug)
-     plug(Pleroma.Plugs.SessionAuthenticationPlug)
-     plug(Pleroma.Plugs.LegacyAuthenticationPlug)
-     plug(Pleroma.Plugs.AuthenticationPlug)
-     plug(Pleroma.Plugs.UserEnabledPlug)
-     plug(Pleroma.Plugs.SetUserSessionIdPlug)
+     plug(:authenticate)
+     plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
+   end
+   pipeline :api do
+     plug(:expect_public_instance_or_authentication)
+     plug(:base_api)
+     plug(:after_auth)
+     plug(Pleroma.Plugs.IdempotencyPlug)
+   end
+   pipeline :authenticated_api do
+     plug(:expect_authentication)
+     plug(:base_api)
+     plug(:after_auth)
      plug(Pleroma.Plugs.EnsureAuthenticatedPlug)
      plug(Pleroma.Plugs.IdempotencyPlug)
    end
  
    pipeline :admin_api do
-     plug(:accepts, ["json"])
-     plug(:fetch_session)
-     plug(Pleroma.Plugs.OAuthPlug)
-     plug(Pleroma.Plugs.BasicAuthDecoderPlug)
-     plug(Pleroma.Plugs.UserFetcherPlug)
-     plug(Pleroma.Plugs.SessionAuthenticationPlug)
-     plug(Pleroma.Plugs.LegacyAuthenticationPlug)
-     plug(Pleroma.Plugs.AuthenticationPlug)
+     plug(:expect_authentication)
+     plug(:base_api)
      plug(Pleroma.Plugs.AdminSecretAuthenticationPlug)
-     plug(Pleroma.Plugs.UserEnabledPlug)
-     plug(Pleroma.Plugs.SetUserSessionIdPlug)
+     plug(:after_auth)
      plug(Pleroma.Plugs.EnsureAuthenticatedPlug)
      plug(Pleroma.Plugs.UserIsAdminPlug)
      plug(Pleroma.Plugs.IdempotencyPlug)
    end
  
    pipeline :mastodon_html do
-     plug(:accepts, ["html"])
-     plug(:fetch_session)
-     plug(Pleroma.Plugs.OAuthPlug)
-     plug(Pleroma.Plugs.BasicAuthDecoderPlug)
-     plug(Pleroma.Plugs.UserFetcherPlug)
-     plug(Pleroma.Plugs.SessionAuthenticationPlug)
-     plug(Pleroma.Plugs.LegacyAuthenticationPlug)
-     plug(Pleroma.Plugs.AuthenticationPlug)
-     plug(Pleroma.Plugs.UserEnabledPlug)
-     plug(Pleroma.Plugs.SetUserSessionIdPlug)
-     plug(Pleroma.Plugs.EnsureUserKeyPlug)
+     plug(:browser)
+     plug(:authenticate)
+     plug(:after_auth)
    end
  
    pipeline :pleroma_html do
-     plug(:accepts, ["html"])
-     plug(:fetch_session)
-     plug(Pleroma.Plugs.OAuthPlug)
-     plug(Pleroma.Plugs.BasicAuthDecoderPlug)
-     plug(Pleroma.Plugs.UserFetcherPlug)
-     plug(Pleroma.Plugs.SessionAuthenticationPlug)
-     plug(Pleroma.Plugs.AuthenticationPlug)
+     plug(:browser)
+     plug(:authenticate)
      plug(Pleroma.Plugs.EnsureUserKeyPlug)
    end
  
  
    pipeline :config do
      plug(:accepts, ["json", "xml"])
+     plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
    end
  
    pipeline :pleroma_api do
      plug(:accepts, ["html", "json"])
+     plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
    end
  
    pipeline :mailbox_preview do
      post("/users/follow", AdminAPIController, :user_follow)
      post("/users/unfollow", AdminAPIController, :user_unfollow)
  
+     put("/users/disable_mfa", AdminAPIController, :disable_mfa)
      delete("/users", AdminAPIController, :user_delete)
      post("/users", AdminAPIController, :users_create)
      patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation)
  
      get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset)
      patch("/users/force_password_reset", AdminAPIController, :force_password_reset)
+     get("/users/:nickname/credentials", AdminAPIController, :show_user_credentials)
+     patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials)
  
      get("/users", AdminAPIController, :list_users)
      get("/users/:nickname", AdminAPIController, :user_show)
      patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email)
  
      get("/reports", AdminAPIController, :list_reports)
-     get("/grouped_reports", AdminAPIController, :list_grouped_reports)
      get("/reports/:id", AdminAPIController, :report_show)
      patch("/reports", AdminAPIController, :reports_update)
      post("/reports/:id/notes", AdminAPIController, :report_notes_create)
      delete("/reports/:report_id/notes/:id", AdminAPIController, :report_notes_delete)
  
-     put("/statuses/:id", AdminAPIController, :status_update)
-     delete("/statuses/:id", AdminAPIController, :status_delete)
-     get("/statuses", AdminAPIController, :list_statuses)
+     get("/statuses/:id", StatusController, :show)
+     put("/statuses/:id", StatusController, :update)
+     delete("/statuses/:id", StatusController, :delete)
+     get("/statuses", StatusController, :index)
  
      get("/config", AdminAPIController, :config_show)
      post("/config", AdminAPIController, :config_update)
      get("/config/descriptions", AdminAPIController, :config_descriptions)
+     get("/need_reboot", AdminAPIController, :need_reboot)
      get("/restart", AdminAPIController, :restart)
  
      get("/moderation_log", AdminAPIController, :list_log)
  
      post("/reload_emoji", AdminAPIController, :reload_emoji)
      get("/stats", AdminAPIController, :stats)
+     get("/oauth_app", AdminAPIController, :oauth_app_list)
+     post("/oauth_app", AdminAPIController, :oauth_app_create)
+     patch("/oauth_app/:id", AdminAPIController, :oauth_app_update)
+     delete("/oauth_app/:id", AdminAPIController, :oauth_app_delete)
    end
  
    scope "/api/pleroma/emoji", Pleroma.Web.PleromaAPI do
+     # Modifying packs
      scope "/packs" do
-       # Modifying packs
        pipe_through(:admin_api)
  
-       post("/import_from_fs", EmojiAPIController, :import_from_fs)
+       get("/import", EmojiPackController, :import_from_filesystem)
+       get("/remote", EmojiPackController, :remote)
+       post("/download", EmojiPackController, :download)
  
-       post("/:pack_name/update_file", EmojiAPIController, :update_file)
-       post("/:pack_name/update_metadata", EmojiAPIController, :update_metadata)
-       put("/:name", EmojiAPIController, :create)
-       delete("/:name", EmojiAPIController, :delete)
-       post("/download_from", EmojiAPIController, :download_from)
-       post("/list_from", EmojiAPIController, :list_from)
+       post("/:name", EmojiPackController, :create)
+       patch("/:name", EmojiPackController, :update)
+       delete("/:name", EmojiPackController, :delete)
+       post("/:name/files", EmojiPackController, :add_file)
+       patch("/:name/files", EmojiPackController, :update_file)
+       delete("/:name/files", EmojiPackController, :delete_file)
      end
  
+     # Pack info / downloading
      scope "/packs" do
-       # Pack info / downloading
-       get("/", EmojiAPIController, :list_packs)
-       get("/:name/download_shared/", EmojiAPIController, :download_shared)
+       pipe_through(:api)
+       get("/", EmojiPackController, :index)
+       get("/:name", EmojiPackController, :show)
+       get("/:name/archive", EmojiPackController, :archive)
      end
    end
  
      post("/follow_import", UtilController, :follow_import)
    end
  
+   scope "/api/pleroma", Pleroma.Web.PleromaAPI do
+     pipe_through(:authenticated_api)
+     get("/accounts/mfa", TwoFactorAuthenticationController, :settings)
+     get("/accounts/mfa/backup_codes", TwoFactorAuthenticationController, :backup_codes)
+     get("/accounts/mfa/setup/:method", TwoFactorAuthenticationController, :setup)
+     post("/accounts/mfa/confirm/:method", TwoFactorAuthenticationController, :confirm)
+     delete("/accounts/mfa/:method", TwoFactorAuthenticationController, :disable)
+   end
    scope "/oauth", Pleroma.Web.OAuth do
      scope [] do
        pipe_through(:oauth)
      post("/revoke", OAuthController, :token_revoke)
      get("/registration_details", OAuthController, :registration_details)
  
+     post("/mfa/challenge", MFAController, :challenge)
+     post("/mfa/verify", MFAController, :verify, as: :mfa_verify)
+     get("/mfa", MFAController, :show)
      scope [] do
        pipe_through(:browser)
  
    scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
      pipe_through(:api)
  
-     get("/statuses/:id/reactions/:emoji", PleromaAPIController, :emoji_reactions_by)
-     get("/statuses/:id/reactions", PleromaAPIController, :emoji_reactions_by)
+     get("/statuses/:id/reactions/:emoji", EmojiReactionController, :index)
+     get("/statuses/:id/reactions", EmojiReactionController, :index)
    end
  
    scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
      scope [] do
        pipe_through(:authenticated_api)
  
-       get("/conversations/:id/statuses", PleromaAPIController, :conversation_statuses)
-       get("/conversations/:id", PleromaAPIController, :conversation)
-       post("/conversations/read", PleromaAPIController, :read_conversations)
-     end
-     scope [] do
-       pipe_through(:authenticated_api)
+       get("/conversations/:id/statuses", ConversationController, :statuses)
+       get("/conversations/:id", ConversationController, :show)
+       post("/conversations/read", ConversationController, :mark_as_read)
+       patch("/conversations/:id", ConversationController, :update)
  
-       patch("/conversations/:id", PleromaAPIController, :update_conversation)
-       put("/statuses/:id/reactions/:emoji", PleromaAPIController, :react_with_emoji)
-       delete("/statuses/:id/reactions/:emoji", PleromaAPIController, :unreact_with_emoji)
-       post("/notifications/read", PleromaAPIController, :read_notification)
+       put("/statuses/:id/reactions/:emoji", EmojiReactionController, :create)
+       delete("/statuses/:id/reactions/:emoji", EmojiReactionController, :delete)
+       post("/notifications/read", NotificationController, :mark_as_read)
  
        patch("/accounts/update_avatar", AccountController, :update_avatar)
        patch("/accounts/update_banner", AccountController, :update_banner)
        get("/mascot", MascotController, :show)
        put("/mascot", MascotController, :update)
  
-       post("/scrobble", ScrobbleController, :new_scrobble)
+       post("/scrobble", ScrobbleController, :create)
      end
  
      scope [] do
  
    scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
      pipe_through(:api)
-     get("/accounts/:id/scrobbles", ScrobbleController, :user_scrobbles)
+     get("/accounts/:id/scrobbles", ScrobbleController, :index)
    end
  
    scope "/api/v1", Pleroma.Web.MastodonAPI do
      pipe_through(:authenticated_api)
  
      get("/accounts/verify_credentials", AccountController, :verify_credentials)
+     patch("/accounts/update_credentials", AccountController, :update_credentials)
  
      get("/accounts/relationships", AccountController, :relationships)
      get("/accounts/:id/lists", AccountController, :lists)
-     get("/accounts/:id/identity_proofs", MastodonAPIController, :empty_array)
-     get("/follow_requests", FollowRequestController, :index)
+     get("/accounts/:id/identity_proofs", AccountController, :identity_proofs)
+     get("/endorsements", AccountController, :endorsements)
      get("/blocks", AccountController, :blocks)
      get("/mutes", AccountController, :mutes)
  
-     get("/timelines/home", TimelineController, :home)
-     get("/timelines/direct", TimelineController, :direct)
+     post("/follows", AccountController, :follow_by_uri)
+     post("/accounts/:id/follow", AccountController, :follow)
+     post("/accounts/:id/unfollow", AccountController, :unfollow)
+     post("/accounts/:id/block", AccountController, :block)
+     post("/accounts/:id/unblock", AccountController, :unblock)
+     post("/accounts/:id/mute", AccountController, :mute)
+     post("/accounts/:id/unmute", AccountController, :unmute)
  
-     get("/favourites", StatusController, :favourites)
-     get("/bookmarks", StatusController, :bookmarks)
+     get("/apps/verify_credentials", AppController, :verify_credentials)
  
-     get("/notifications", NotificationController, :index)
-     get("/notifications/:id", NotificationController, :show)
-     post("/notifications/clear", NotificationController, :clear)
-     post("/notifications/dismiss", NotificationController, :dismiss)
-     delete("/notifications/destroy_multiple", NotificationController, :destroy_multiple)
+     get("/conversations", ConversationController, :index)
+     post("/conversations/:id/read", ConversationController, :mark_as_read)
  
-     get("/scheduled_statuses", ScheduledActivityController, :index)
-     get("/scheduled_statuses/:id", ScheduledActivityController, :show)
+     get("/domain_blocks", DomainBlockController, :index)
+     post("/domain_blocks", DomainBlockController, :create)
+     delete("/domain_blocks", DomainBlockController, :delete)
+     get("/filters", FilterController, :index)
+     post("/filters", FilterController, :create)
+     get("/filters/:id", FilterController, :show)
+     put("/filters/:id", FilterController, :update)
+     delete("/filters/:id", FilterController, :delete)
+     get("/follow_requests", FollowRequestController, :index)
+     post("/follow_requests/:id/authorize", FollowRequestController, :authorize)
+     post("/follow_requests/:id/reject", FollowRequestController, :reject)
  
      get("/lists", ListController, :index)
      get("/lists/:id", ListController, :show)
      get("/lists/:id/accounts", ListController, :list_accounts)
  
-     get("/domain_blocks", DomainBlockController, :index)
+     delete("/lists/:id", ListController, :delete)
+     post("/lists", ListController, :create)
+     put("/lists/:id", ListController, :update)
+     post("/lists/:id/accounts", ListController, :add_to_list)
+     delete("/lists/:id/accounts", ListController, :remove_from_list)
  
-     get("/filters", FilterController, :index)
+     get("/markers", MarkerController, :index)
+     post("/markers", MarkerController, :upsert)
  
-     get("/suggestions", SuggestionController, :index)
+     post("/media", MediaController, :create)
+     get("/media/:id", MediaController, :show)
+     put("/media/:id", MediaController, :update)
  
-     get("/conversations", ConversationController, :index)
-     post("/conversations/:id/read", ConversationController, :read)
+     get("/notifications", NotificationController, :index)
+     get("/notifications/:id", NotificationController, :show)
  
-     get("/endorsements", AccountController, :endorsements)
+     post("/notifications/:id/dismiss", NotificationController, :dismiss)
+     post("/notifications/clear", NotificationController, :clear)
+     delete("/notifications/destroy_multiple", NotificationController, :destroy_multiple)
+     # Deprecated: was removed in Mastodon v3, use `/notifications/:id/dismiss` instead
+     post("/notifications/dismiss", NotificationController, :dismiss_via_body)
  
-     patch("/accounts/update_credentials", AccountController, :update_credentials)
+     post("/polls/:id/votes", PollController, :vote)
+     post("/reports", ReportController, :create)
+     get("/scheduled_statuses", ScheduledActivityController, :index)
+     get("/scheduled_statuses/:id", ScheduledActivityController, :show)
+     put("/scheduled_statuses/:id", ScheduledActivityController, :update)
+     delete("/scheduled_statuses/:id", ScheduledActivityController, :delete)
+     # Unlike `GET /api/v1/accounts/:id/favourites`, demands authentication
+     get("/favourites", StatusController, :favourites)
+     get("/bookmarks", StatusController, :bookmarks)
  
      post("/statuses", StatusController, :create)
      delete("/statuses/:id", StatusController, :delete)
      post("/statuses/:id/reblog", StatusController, :reblog)
      post("/statuses/:id/unreblog", StatusController, :unreblog)
      post("/statuses/:id/favourite", StatusController, :favourite)
      post("/statuses/:id/mute", StatusController, :mute_conversation)
      post("/statuses/:id/unmute", StatusController, :unmute_conversation)
  
-     put("/scheduled_statuses/:id", ScheduledActivityController, :update)
-     delete("/scheduled_statuses/:id", ScheduledActivityController, :delete)
-     post("/polls/:id/votes", PollController, :vote)
-     post("/media", MediaController, :create)
-     put("/media/:id", MediaController, :update)
-     delete("/lists/:id", ListController, :delete)
-     post("/lists", ListController, :create)
-     put("/lists/:id", ListController, :update)
-     post("/lists/:id/accounts", ListController, :add_to_list)
-     delete("/lists/:id/accounts", ListController, :remove_from_list)
-     post("/filters", FilterController, :create)
-     get("/filters/:id", FilterController, :show)
-     put("/filters/:id", FilterController, :update)
-     delete("/filters/:id", FilterController, :delete)
-     post("/reports", ReportController, :create)
-     post("/follows", AccountController, :follows)
-     post("/accounts/:id/follow", AccountController, :follow)
-     post("/accounts/:id/unfollow", AccountController, :unfollow)
-     post("/accounts/:id/block", AccountController, :block)
-     post("/accounts/:id/unblock", AccountController, :unblock)
-     post("/accounts/:id/mute", AccountController, :mute)
-     post("/accounts/:id/unmute", AccountController, :unmute)
-     post("/follow_requests/:id/authorize", FollowRequestController, :authorize)
-     post("/follow_requests/:id/reject", FollowRequestController, :reject)
-     post("/domain_blocks", DomainBlockController, :create)
-     delete("/domain_blocks", DomainBlockController, :delete)
      post("/push/subscription", SubscriptionController, :create)
-     get("/push/subscription", SubscriptionController, :get)
+     get("/push/subscription", SubscriptionController, :show)
      put("/push/subscription", SubscriptionController, :update)
      delete("/push/subscription", SubscriptionController, :delete)
  
-     get("/markers", MarkerController, :index)
-     post("/markers", MarkerController, :upsert)
+     get("/suggestions", SuggestionController, :index)
+     get("/timelines/home", TimelineController, :home)
+     get("/timelines/direct", TimelineController, :direct)
+     get("/timelines/list/:list_id", TimelineController, :list)
    end
  
    scope "/api/web", Pleroma.Web do
    scope "/api/v1", Pleroma.Web.MastodonAPI do
      pipe_through(:api)
  
-     post("/accounts", AccountController, :create)
      get("/accounts/search", SearchController, :account_search)
+     get("/search", SearchController, :search)
+     get("/accounts/:id/statuses", AccountController, :statuses)
+     get("/accounts/:id/followers", AccountController, :followers)
+     get("/accounts/:id/following", AccountController, :following)
+     get("/accounts/:id", AccountController, :show)
+     post("/accounts", AccountController, :create)
  
      get("/instance", InstanceController, :show)
      get("/instance/peers", InstanceController, :peers)
  
      post("/apps", AppController, :create)
-     get("/apps/verify_credentials", AppController, :verify_credentials)
  
+     get("/statuses", StatusController, :index)
+     get("/statuses/:id", StatusController, :show)
+     get("/statuses/:id/context", StatusController, :context)
      get("/statuses/:id/card", StatusController, :card)
      get("/statuses/:id/favourited_by", StatusController, :favourited_by)
      get("/statuses/:id/reblogged_by", StatusController, :reblogged_by)
  
      get("/timelines/public", TimelineController, :public)
      get("/timelines/tag/:tag", TimelineController, :hashtag)
-     get("/timelines/list/:list_id", TimelineController, :list)
-     get("/statuses", StatusController, :index)
-     get("/statuses/:id", StatusController, :show)
-     get("/statuses/:id/context", StatusController, :context)
  
      get("/polls/:id", PollController, :show)
-     get("/accounts/:id/statuses", AccountController, :statuses)
-     get("/accounts/:id/followers", AccountController, :followers)
-     get("/accounts/:id/following", AccountController, :following)
-     get("/accounts/:id", AccountController, :show)
-     get("/search", SearchController, :search)
    end
  
    scope "/api/v2", Pleroma.Web.MastodonAPI do
      pipe_through(:api)
      get("/search", SearchController, :search2)
+     post("/media", MediaController, :create2)
    end
  
    scope "/api", Pleroma.Web do
      )
    end
  
+   scope "/api" do
+     pipe_through(:base_api)
+     get("/openapi", OpenApiSpex.Plug.RenderSpec, [])
+   end
    scope "/api", Pleroma.Web, as: :authenticated_twitter_api do
      pipe_through(:authenticated_api)
  
      get("/oauth_tokens", TwitterAPI.Controller, :oauth_tokens)
      delete("/oauth_tokens/:id", TwitterAPI.Controller, :revoke_token)
  
-     post("/qvitter/statuses/notifications/read", TwitterAPI.Controller, :notifications_read)
-   end
-   pipeline :ap_service_actor do
-     plug(:accepts, ["activity+json", "json"])
+     post(
+       "/qvitter/statuses/notifications/read",
+       TwitterAPI.Controller,
+       :mark_notifications_as_read
+     )
    end
  
    pipeline :ostatus do
    end
  
    scope "/", Pleroma.Web do
-     pipe_through(:ostatus)
-     pipe_through(:http_signature)
+     pipe_through([:ostatus, :http_signature])
  
      get("/objects/:uuid", OStatus.OStatusController, :object)
      get("/activities/:uuid", OStatus.OStatusController, :activity)
      get("/notice/:id", OStatus.OStatusController, :notice)
      get("/notice/:id/embed_player", OStatus.OStatusController, :notice_player)
  
+     # Mastodon compatibility routes
+     get("/users/:nickname/statuses/:id", OStatus.OStatusController, :object)
+     get("/users/:nickname/statuses/:id/activity", OStatus.OStatusController, :activity)
      get("/users/:nickname/feed", Feed.UserController, :feed, as: :user_feed)
      get("/users/:nickname", Feed.UserController, :feed_redirect, as: :user_feed)
  
      get("/mailer/unsubscribe/:token", Mailer.SubscriptionController, :unsubscribe)
    end
  
-   # Server to Server (S2S) AP interactions
-   pipeline :activitypub do
-     plug(:accepts, ["activity+json", "json"])
-     plug(Pleroma.Web.Plugs.HTTPSignaturePlug)
-     plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
-   end
    scope "/", Pleroma.Web.ActivityPub do
      # XXX: not really ostatus
      pipe_through(:ostatus)
      get("/users/:nickname/outbox", ActivityPubController, :outbox)
    end
  
+   pipeline :ap_service_actor do
+     plug(:accepts, ["activity+json", "json"])
+   end
+   # Server to Server (S2S) AP interactions
+   pipeline :activitypub do
+     plug(:ap_service_actor)
+     plug(:http_signature)
+   end
    # Client to Server (C2S) AP interactions
    pipeline :activitypub_client do
-     plug(:accepts, ["activity+json", "json"])
+     plug(:ap_service_actor)
      plug(:fetch_session)
-     plug(Pleroma.Plugs.OAuthPlug)
-     plug(Pleroma.Plugs.BasicAuthDecoderPlug)
-     plug(Pleroma.Plugs.UserFetcherPlug)
-     plug(Pleroma.Plugs.SessionAuthenticationPlug)
-     plug(Pleroma.Plugs.LegacyAuthenticationPlug)
-     plug(Pleroma.Plugs.AuthenticationPlug)
-     plug(Pleroma.Plugs.UserEnabledPlug)
-     plug(Pleroma.Plugs.SetUserSessionIdPlug)
-     plug(Pleroma.Plugs.EnsureUserKeyPlug)
+     plug(:authenticate)
+     plug(:after_auth)
    end
  
    scope "/", Pleroma.Web.ActivityPub do
      post("/users/:nickname/outbox", ActivityPubController, :update_outbox)
      post("/api/ap/upload_media", ActivityPubController, :upload_media)
  
+     # The following two are S2S as well, see `ActivityPub.fetch_follow_information_for_user/1`:
      get("/users/:nickname/followers", ActivityPubController, :followers)
      get("/users/:nickname/following", ActivityPubController, :following)
    end
      post("/auth/password", MastodonAPI.AuthController, :password_reset)
  
      get("/web/*path", MastoFEController, :index)
 +
 +    get("/embed/:id", EmbedController, :show)
    end
  
-   pipeline :remote_media do
-   end
    scope "/proxy/", Pleroma.Web.MediaProxy do
-     pipe_through(:remote_media)
      get("/:sig/:url", MediaProxyController, :remote)
      get("/:sig/:url/:filename", MediaProxyController, :remote)
    end
      end
    end
  
+   # Test-only routes needed to test action dispatching and plug chain execution
+   if Pleroma.Config.get(:env) == :test do
+     @test_actions [
+       :do_oauth_check,
+       :fallback_oauth_check,
+       :skip_oauth_check,
+       :fallback_oauth_skip_publicity_check,
+       :skip_oauth_skip_publicity_check,
+       :missing_oauth_check_definition
+     ]
+     scope "/test/api", Pleroma.Tests do
+       pipe_through(:api)
+       for action <- @test_actions do
+         get("/#{action}", AuthTestController, action)
+       end
+     end
+     scope "/test/authenticated_api", Pleroma.Tests do
+       pipe_through(:authenticated_api)
+       for action <- @test_actions do
+         get("/#{action}", AuthTestController, action)
+       end
+     end
+   end
    scope "/", Pleroma.Web.MongooseIM do
      get("/user_exists", MongooseIMController, :user_exists)
      get("/check_password", MongooseIMController, :check_password)
index 6bf8fac29509fe7ddbfd313e430f2d71eb8f501c,0000000000000000000000000000000000000000..05a3f0ee305acf26c0cc469ace6d0f8b7b82fee4
mode 100644,000000..100644
--- /dev/null
@@@ -1,76 -1,0 +1,76 @@@
-     <a class="u-url" rel="author noopener" href="<%= User.profile_url(@author) %>">
 +<div>
 +  <div class="p-author h-card">
-         <bdi><%= raw (@author.name |> Formatter.emojify(emoji_for_user(@author))) %></bdi>
++    <a class="u-url" rel="author noopener" href="<%= @author.ap_id %>">
 +      <div class="avatar">
 +        <img src="<%= User.avatar_url(@author) |> MediaProxy.url %>" width="48" height="48" alt="">
 +      </div>
 +      <span class="display-name" style="padding-left: 0.5em;">
++        <bdi><%= raw (@author.name |> Formatter.emojify(@author.emoji)) %></bdi>
 +        <span class="nickname"><%= full_nickname(@author) %></span>
 +      </span>
 +    </a>
 +  </div>
 +
 +  <div class="activity-content" >
 +    <%= if status_title(@activity) != "" do %>
 +      <details <%= if open_content?() do %>open<% end %>>
 +        <summary><%= raw status_title(@activity) %></summary>
 +        <div><%= activity_content(@activity) %></div>
 +      </details>
 +    <% else %>
 +      <div><%= activity_content(@activity) %></div>
 +    <% end %>
 +    <%= for %{"name" => name, "url" => [url | _]} <- attachments(@activity) do %>
 +      <div class="attachment">
 +      <%= if sensitive?(@activity) do %>
 +        <details class="nsfw">
 +          <summary onClick="updateHeight()"><%= Gettext.gettext("sensitive media") %></summary>
 +          <div class="nsfw-content">
 +            <%= render("_attachment.html", %{name: name, url: url["href"],
 +                                             mediaType: fetch_media_type(url)}) %>
 +          </div>
 +        </details>
 +      <% else %>
 +        <%= render("_attachment.html", %{name: name, url: url["href"],
 +                                         mediaType: fetch_media_type(url)}) %>
 +      <% end %>
 +      </div>
 +    <% end %>
 +  </div>
 +
 +  <dl class="counts pull-right">
 +    <dt><%= Gettext.gettext("replies") %></dt><dd><%= @counts.replies %></dd>
 +    <dt><%= Gettext.gettext("announces") %></dt><dd><%= @counts.announces %></dd>
 +    <dt><%= Gettext.gettext("likes") %></dt><dd><%= @counts.likes %></dd>
 +  </dl>
 +
 +  <p class="date pull-left">
 +    <%= link published(@activity), to: activity_url(@author, @activity) %>
 +  </p>
 +</div>
 +
 +<script>
 +function updateHeight() {
 +  window.requestAnimationFrame(function(){
 +    var height = document.getElementsByTagName('html')[0].scrollHeight;
 +
 +    window.parent.postMessage({
 +      type: 'setHeightPleromaEmbed',
 +      id: window.parentId,
 +      height: height,
 +    }, '*');
 +  })
 +}
 +
 +window.addEventListener('message', function(e){
 +  var data = e.data || {};
 +
 +  if (!window.parent || data.type !== 'setHeightPleromaEmbed') {
 +    return;
 +  }
 +
 +  window.parentId = data.id
 +
 +  updateHeight()
 +});
 +</script>
index 57ae4f802aa925c82fa48e1efff1073785e231b4,0000000000000000000000000000000000000000..8b905f0705d6aa1b3da25b848dbaa99f30b4dba9
mode 100644,000000..100644
--- /dev/null
@@@ -1,14 -1,0 +1,15 @@@
 +<!DOCTYPE html>
 +<html>
 +  <head>
 +    <meta charset="utf-8" />
 +    <meta name="viewport" content="width=device-width,initial-scale=1,minimal-ui" />
 +    <title><%= Pleroma.Config.get([:instance, :name]) %></title>
 +    <meta content='noindex' name='robots'>
 +    <%= Phoenix.HTML.raw(assigns[:meta] || "") %>
 +    <link rel="stylesheet" href="/embed.css">
++    <base target="_parent">
 +  </head>
 +  <body>
 +    <%= render @view_module, @view_template, assigns %>
 +  </body>
 +</html>
index 77536835bf7cc7fac5aed38ef8b72988cf01819f,0000000000000000000000000000000000000000..5f50bd155b7baa6d3bfcb7b61d33795919cb0ade
mode 100644,000000..100644
--- /dev/null
@@@ -1,83 -1,0 +1,74 @@@
-   defp emoji_for_user(%User{} = user) do
-     user.source_data
-     |> Map.get("tag", [])
-     |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
-     |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
-       {String.trim(name, ":"), url}
-     end)
-   end
 +# Pleroma: A lightweight social networking server
 +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 +# SPDX-License-Identifier: AGPL-3.0-only
 +
 +defmodule Pleroma.Web.EmbedView do
 +  use Pleroma.Web, :view
 +
 +  alias Calendar.Strftime
 +  alias Pleroma.Activity
 +  alias Pleroma.Emoji.Formatter
 +  alias Pleroma.Object
 +  alias Pleroma.User
 +  alias Pleroma.Web.Gettext
 +  alias Pleroma.Web.MediaProxy
 +  alias Pleroma.Web.Metadata.Utils
 +  alias Pleroma.Web.Router.Helpers
 +
 +  use Phoenix.HTML
 +
 +  @media_types ["image", "audio", "video"]
 +
 +  defp fetch_media_type(%{"mediaType" => mediaType}) do
 +    Utils.fetch_media_type(@media_types, mediaType)
 +  end
 +
 +  defp open_content? do
 +    Pleroma.Config.get(
 +      [:frontend_configurations, :collapse_message_with_subjects],
 +      true
 +    )
 +  end
 +
 +  defp full_nickname(user) do
 +    %{host: host} = URI.parse(user.ap_id)
 +    "@" <> user.nickname <> "@" <> host
 +  end
 +
 +  defp status_title(%Activity{object: %Object{data: %{"name" => name}}}) when is_binary(name),
 +    do: name
 +
 +  defp status_title(%Activity{object: %Object{data: %{"summary" => summary}}})
 +       when is_binary(summary),
 +       do: summary
 +
 +  defp status_title(_), do: nil
 +
 +  defp activity_content(%Activity{object: %Object{data: %{"content" => content}}}) do
 +    content |> Pleroma.HTML.filter_tags() |> raw()
 +  end
 +
 +  defp activity_content(_), do: nil
 +
 +  defp activity_url(%User{local: true}, activity) do
 +    Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, activity)
 +  end
 +
 +  defp activity_url(%User{local: false}, %Activity{object: %Object{data: data}}) do
 +    data["url"] || data["external_url"] || data["id"]
 +  end
 +
 +  defp attachments(%Activity{object: %Object{data: %{"attachment" => attachments}}}) do
 +    attachments
 +  end
 +
 +  defp sensitive?(%Activity{object: %Object{data: %{"sensitive" => sensitive}}}) do
 +    sensitive
 +  end
 +
 +  defp published(%Activity{object: %Object{data: %{"published" => published}}}) do
 +    published
 +    |> NaiveDateTime.from_iso8601!()
 +    |> Strftime.strftime!("%B %d, %Y, %l:%M %p")
 +  end
 +end