diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/activity.ex | 15 | ||||
-rw-r--r-- | lib/pleroma/emails/mailer.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/emails/user_email.ex | 40 | ||||
-rw-r--r-- | lib/pleroma/plugs/oauth_plug.ex | 28 | ||||
-rw-r--r-- | lib/pleroma/web/common_api/common_api.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 69 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/push_subscription_view.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/web/push/push.ex | 120 | ||||
-rw-r--r-- | lib/pleroma/web/push/subscription.ex | 14 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 18 | ||||
-rw-r--r-- | lib/pleroma/web/templates/twitter_api/util/password_reset_failed.html.eex | 1 | ||||
-rw-r--r-- | lib/pleroma/web/templates/twitter_api/util/password_reset_success.html.eex | 1 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/controllers/util_controller.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api.ex | 19 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api_controller.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/views/activity_view.ex | 6 |
16 files changed, 258 insertions, 112 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index c065f3b6c..200addd6e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -3,6 +3,14 @@ defmodule Pleroma.Activity do alias Pleroma.{Repo, Activity, Notification} import Ecto.Query + # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 + @mastodon_notification_types %{ + "Create" => "mention", + "Follow" => "follow", + "Announce" => "reblog", + "Like" => "favourite" + } + schema "activities" do field(:data, :map) field(:local, :boolean, default: true) @@ -88,4 +96,11 @@ defmodule Pleroma.Activity do end def get_in_reply_to_activity(_), do: nil + + for {ap_type, type} <- @mastodon_notification_types do + def mastodon_notification_type(%Activity{data: %{"type" => unquote(ap_type)}}), + do: unquote(type) + end + + def mastodon_notification_type(%Activity{}), do: nil end diff --git a/lib/pleroma/emails/mailer.ex b/lib/pleroma/emails/mailer.ex new file mode 100644 index 000000000..14ed32ea8 --- /dev/null +++ b/lib/pleroma/emails/mailer.ex @@ -0,0 +1,3 @@ +defmodule Pleroma.Mailer do + use Swoosh.Mailer, otp_app: :pleroma +end diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex new file mode 100644 index 000000000..9cdf002f3 --- /dev/null +++ b/lib/pleroma/emails/user_email.ex @@ -0,0 +1,40 @@ +defmodule Pleroma.UserEmail do + @moduledoc "User emails" + + import Swoosh.Email + + alias Pleroma.Web.{Endpoint, Router} + + defp instance_config, do: Pleroma.Config.get(:instance) + + defp instance_name, do: instance_config()[:name] + + defp sender do + {instance_name(), instance_config()[:email]} + end + + defp recipient(email, nil), do: email + defp recipient(email, name), do: {name, email} + + def password_reset_email(user, password_reset_token) when is_binary(password_reset_token) do + password_reset_url = + Router.Helpers.util_url( + Endpoint, + :show_password_reset, + password_reset_token + ) + + html_body = """ + <h3>Reset your password at #{instance_name()}</h3> + <p>Someone has requested password change for your account at #{instance_name()}.</p> + <p>If it was you, visit the following link to proceed: <a href="#{password_reset_url}">reset password</a>.</p> + <p>If it was someone else, nothing to worry about: your data is secure and your password has not been changed.</p> + """ + + new() + |> to(recipient(user.email, user.name)) + |> from(sender()) + |> subject("Password reset") + |> html_body(html_body) + end +end diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex index 8b99a74d1..13c914c1b 100644 --- a/lib/pleroma/plugs/oauth_plug.ex +++ b/lib/pleroma/plugs/oauth_plug.ex @@ -15,10 +15,10 @@ defmodule Pleroma.Plugs.OAuthPlug do def call(%{assigns: %{user: %User{}}} = conn, _), do: conn def call(conn, _) do - with {:ok, token} <- fetch_token(conn), - {:ok, user} <- fetch_user(token) do + with {:ok, token_str} <- fetch_token_str(conn), + {:ok, user, token_record} <- fetch_user_and_token(token_str) do conn - |> assign(:token, token) + |> assign(:token, token_record) |> assign(:user, user) else _ -> conn @@ -27,12 +27,12 @@ defmodule Pleroma.Plugs.OAuthPlug do # Gets user by token # - @spec fetch_user(String.t()) :: {:ok, User.t()} | nil - defp fetch_user(token) do + @spec fetch_user_and_token(String.t()) :: {:ok, User.t(), Token.t()} | nil + defp fetch_user_and_token(token) do query = from(q in Token, where: q.token == ^token, preload: [:user]) - with %Token{user: %{info: %{deactivated: false} = _} = user} <- Repo.one(query) do - {:ok, user} + with %Token{user: %{info: %{deactivated: false} = _} = user} = token_record <- Repo.one(query) do + {:ok, user, token_record} end end @@ -48,23 +48,23 @@ defmodule Pleroma.Plugs.OAuthPlug do # Gets token from headers # - @spec fetch_token(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()} - defp fetch_token(%Plug.Conn{} = conn) do + @spec fetch_token_str(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()} + defp fetch_token_str(%Plug.Conn{} = conn) do headers = get_req_header(conn, "authorization") - with :no_token_found <- fetch_token(headers), + with :no_token_found <- fetch_token_str(headers), do: fetch_token_from_session(conn) end - @spec fetch_token(Keyword.t()) :: :no_token_found | {:ok, String.t()} - defp fetch_token([]), do: :no_token_found + @spec fetch_token_str(Keyword.t()) :: :no_token_found | {:ok, String.t()} + defp fetch_token_str([]), do: :no_token_found - defp fetch_token([token | tail]) do + defp fetch_token_str([token | tail]) do trimmed_token = String.trim(token) case Regex.run(@realm_reg, trimmed_token) do [_, match] -> {:ok, String.trim(match)} - _ -> fetch_token(tail) + _ -> fetch_token_str(tail) end end end diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index e3385310f..f01d36370 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -1,6 +1,7 @@ defmodule Pleroma.Web.CommonAPI do alias Pleroma.{User, Repo, Activity, Object} alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Formatter import Pleroma.Web.CommonAPI.Utils @@ -16,7 +17,8 @@ defmodule Pleroma.Web.CommonAPI do def repeat(id_or_ap_id, user) do with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), - object <- Object.normalize(activity.data["object"]["id"]) do + object <- Object.normalize(activity.data["object"]["id"]), + nil <- Utils.get_existing_announce(user.ap_id, object) do ActivityPub.announce(user, object) else _ -> @@ -36,7 +38,8 @@ defmodule Pleroma.Web.CommonAPI do def favorite(id_or_ap_id, user) do with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), - object <- Object.normalize(activity.data["object"]["id"]) do + object <- Object.normalize(activity.data["object"]["id"]), + nil <- Utils.get_existing_like(user.ap_id, object) do ActivityPub.like(user, object) else _ -> diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 5c8602322..0414d73d8 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -1055,52 +1055,37 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do actor = User.get_cached_by_ap_id(activity.data["actor"]) + parent_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + mastodon_type = Activity.mastodon_notification_type(activity) - created_at = - NaiveDateTime.to_iso8601(created_at) - |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false) - - id = id |> to_string + response = %{ + id: to_string(id), + type: mastodon_type, + created_at: CommonAPI.Utils.to_masto_date(created_at), + account: AccountView.render("account.json", %{user: actor, for: user}) + } - case activity.data["type"] do - "Create" -> - %{ - id: id, - type: "mention", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}), + case mastodon_type do + "mention" -> + response + |> Map.merge(%{ status: StatusView.render("status.json", %{activity: activity, for: user}) - } + }) - "Like" -> - liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + "favourite" -> + response + |> Map.merge(%{ + status: StatusView.render("status.json", %{activity: parent_activity, for: user}) + }) - %{ - id: id, - type: "favourite", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}), - status: StatusView.render("status.json", %{activity: liked_activity, for: user}) - } + "reblog" -> + response + |> Map.merge(%{ + status: StatusView.render("status.json", %{activity: parent_activity, for: user}) + }) - "Announce" -> - announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) - - %{ - id: id, - type: "reblog", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}), - status: StatusView.render("status.json", %{activity: announced_activity, for: user}) - } - - "Follow" -> - %{ - id: id, - type: "follow", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}) - } + "follow" -> + response _ -> nil @@ -1167,6 +1152,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def create_push_subscription(%{assigns: %{user: user, token: token}} = conn, params) do + true = Pleroma.Web.Push.enabled() Pleroma.Web.Push.Subscription.delete_if_exists(user, token) {:ok, subscription} = Pleroma.Web.Push.Subscription.create(user, token, params) view = PushSubscriptionView.render("push_subscription.json", subscription: subscription) @@ -1174,6 +1160,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def get_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do + true = Pleroma.Web.Push.enabled() subscription = Pleroma.Web.Push.Subscription.get(user, token) view = PushSubscriptionView.render("push_subscription.json", subscription: subscription) json(conn, view) @@ -1183,12 +1170,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do %{assigns: %{user: user, token: token}} = conn, params ) do + true = Pleroma.Web.Push.enabled() {:ok, subscription} = Pleroma.Web.Push.Subscription.update(user, token, params) view = PushSubscriptionView.render("push_subscription.json", subscription: subscription) json(conn, view) end def delete_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do + true = Pleroma.Web.Push.enabled() {:ok, _response} = Pleroma.Web.Push.Subscription.delete(user, token) json(conn, %{}) end diff --git a/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex b/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex index c8b95d14c..67e86294e 100644 --- a/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex +++ b/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex @@ -5,7 +5,12 @@ defmodule Pleroma.Web.MastodonAPI.PushSubscriptionView do %{ id: to_string(subscription.id), endpoint: subscription.endpoint, - alerts: Map.get(subscription.data, "alerts") + alerts: Map.get(subscription.data, "alerts"), + server_key: server_key() } end + + defp server_key do + Keyword.get(Application.get_env(:web_push_encryption, :vapid_details), :public_key) + end end diff --git a/lib/pleroma/web/push/push.ex b/lib/pleroma/web/push/push.ex index 5a873ec19..477943450 100644 --- a/lib/pleroma/web/push/push.ex +++ b/lib/pleroma/web/push/push.ex @@ -9,67 +9,99 @@ defmodule Pleroma.Web.Push do @types ["Create", "Follow", "Announce", "Like"] - @gcm_api_key nil - def start_link() do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) end - def init(:ok) do - case Application.get_env(:web_push_encryption, :vapid_details) do - nil -> - Logger.warn( - "VAPID key pair is not found. Please, add VAPID configuration to config. Run `mix web_push.gen.keypair` mix task to create a key pair" - ) - - :ignore + def vapid_config() do + Application.get_env(:web_push_encryption, :vapid_details, []) + end - _ -> - {:ok, %{}} + def enabled() do + case vapid_config() do + [] -> false + list when is_list(list) -> true + _ -> false end end def send(notification) do - if Application.get_env(:web_push_encryption, :vapid_details) do + if enabled() do GenServer.cast(Pleroma.Web.Push, {:send, notification}) end end + def init(:ok) do + if !enabled() do + Logger.warn(""" + VAPID key pair is not found. If you wish to enabled web push, please run + + mix web_push.gen.keypair + + and add the resulting output to your configuration file. + """) + + :ignore + else + {:ok, nil} + end + end + def handle_cast( {:send, %{activity: %{data: %{"type" => type}}, user_id: user_id} = notification}, state ) when type in @types do actor = User.get_cached_by_ap_id(notification.activity.data["actor"]) - body = notification |> format(actor) |> Jason.encode!() + + type = Pleroma.Activity.mastodon_notification_type(notification.activity) Subscription |> where(user_id: ^user_id) + |> preload(:token) |> Repo.all() - |> Enum.each(fn record -> - subscription = %{ + |> Enum.filter(fn subscription -> + get_in(subscription.data, ["alerts", type]) || false + end) + |> Enum.each(fn subscription -> + sub = %{ keys: %{ - p256dh: record.key_p256dh, - auth: record.key_auth + p256dh: subscription.key_p256dh, + auth: subscription.key_auth }, - endpoint: record.endpoint + endpoint: subscription.endpoint } - case WebPushEncryption.send_web_push(body, subscription, @gcm_api_key) do + body = + Jason.encode!(%{ + title: format_title(notification), + access_token: subscription.token.token, + body: format_body(notification, actor), + notification_id: notification.id, + notification_type: type, + icon: User.avatar_url(actor), + preferred_locale: "en" + }) + + case WebPushEncryption.send_web_push( + body, + sub, + Application.get_env(:web_push_encryption, :gcm_api_key) + ) do {:ok, %{status_code: code}} when 400 <= code and code < 500 -> Logger.debug("Removing subscription record") - Repo.delete!(record) + Repo.delete!(subscription) :ok {:ok, %{status_code: code}} when 200 <= code and code < 300 -> :ok {:ok, %{status_code: code}} -> - Logger.error("Web Push Nonification failed with code: #{code}") + Logger.error("Web Push Notification failed with code: #{code}") :error _ -> - Logger.error("Web Push Nonification failed with unknown error") + Logger.error("Web Push Notification failed with unknown error") :error end end) @@ -82,35 +114,21 @@ defmodule Pleroma.Web.Push do {:noreply, state} end - def format(%{activity: %{data: %{"type" => "Create"}}}, actor) do - %{ - title: "New Mention", - body: "@#{actor.nickname} has mentiond you", - icon: User.avatar_url(actor) - } - end - - def format(%{activity: %{data: %{"type" => "Follow"}}}, actor) do - %{ - title: "New Follower", - body: "@#{actor.nickname} has followed you", - icon: User.avatar_url(actor) - } - end - - def format(%{activity: %{data: %{"type" => "Announce"}}}, actor) do - %{ - title: "New Announce", - body: "@#{actor.nickname} has announced your post", - icon: User.avatar_url(actor) - } + defp format_title(%{activity: %{data: %{"type" => type}}}) do + case type do + "Create" -> "New Mention" + "Follow" -> "New Follower" + "Announce" -> "New Repeat" + "Like" -> "New Favorite" + end end - def format(%{activity: %{data: %{"type" => "Like"}}}, actor) do - %{ - title: "New Like", - body: "@#{actor.nickname} has liked your post", - icon: User.avatar_url(actor) - } + defp format_body(%{activity: %{data: %{"type" => type}}}, actor) do + case type do + "Create" -> "@#{actor.nickname} has mentioned you" + "Follow" -> "@#{actor.nickname} has followed you" + "Announce" -> "@#{actor.nickname} has repeated your post" + "Like" -> "@#{actor.nickname} has favorited your post" + end end end diff --git a/lib/pleroma/web/push/subscription.ex b/lib/pleroma/web/push/subscription.ex index cfab7a98e..1ad405daf 100644 --- a/lib/pleroma/web/push/subscription.ex +++ b/lib/pleroma/web/push/subscription.ex @@ -37,8 +37,8 @@ defmodule Pleroma.Web.Push.Subscription do user_id: user.id, token_id: token.id, endpoint: endpoint, - key_auth: key_auth, - key_p256dh: key_p256dh, + key_auth: ensure_base64_urlsafe(key_auth), + key_p256dh: ensure_base64_urlsafe(key_p256dh), data: alerts(params) }) end @@ -63,4 +63,14 @@ defmodule Pleroma.Web.Push.Subscription do sub -> Repo.delete(sub) end end + + # Some webpush clients (e.g. iOS Toot!) use an non urlsafe base64 as an encoding for the key. + # However, the web push rfs specify to use base64 urlsafe, and the `web_push_encryption` library we use + # requires the key to be properly encoded. So we just convert base64 to urlsafe base64. + defp ensure_base64_urlsafe(string) do + string + |> String.replace("+", "-") + |> String.replace("/", "_") + |> String.replace("=", "") + end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index ad97698dd..751624e80 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -85,6 +85,15 @@ defmodule Pleroma.Web.Router do plug(:accepts, ["html", "json"]) end + pipeline :mailbox_preview do + plug(:accepts, ["html"]) + + plug(:put_secure_browser_headers, %{ + "content-security-policy" => + "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' 'unsafe-eval'" + }) + end + scope "/api/pleroma", Pleroma.Web.TwitterAPI do pipe_through(:pleroma_api) get("/password_reset/:token", UtilController, :show_password_reset) @@ -268,6 +277,7 @@ defmodule Pleroma.Web.Router do get("/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation) post("/account/register", TwitterAPI.Controller, :register) + post("/account/password_reset", TwitterAPI.Controller, :password_reset) get("/search", TwitterAPI.Controller, :search) get("/statusnet/tags/timeline/:tag", TwitterAPI.Controller, :public_and_external_timeline) @@ -434,6 +444,14 @@ defmodule Pleroma.Web.Router do get("/:sig/:url/:filename", MediaProxyController, :remote) end + if Mix.env() == :dev do + scope "/dev" do + pipe_through([:mailbox_preview]) + + forward("/mailbox", Plug.Swoosh.MailboxPreview, base_path: "/dev/mailbox") + end + end + scope "/", Fallback do get("/registration/:token", RedirectController, :registration_page) get("/*path", RedirectController, :redirector) diff --git a/lib/pleroma/web/templates/twitter_api/util/password_reset_failed.html.eex b/lib/pleroma/web/templates/twitter_api/util/password_reset_failed.html.eex index 58a3736fd..df037c01e 100644 --- a/lib/pleroma/web/templates/twitter_api/util/password_reset_failed.html.eex +++ b/lib/pleroma/web/templates/twitter_api/util/password_reset_failed.html.eex @@ -1 +1,2 @@ <h2>Password reset failed</h2> +<h3><a href="<%= Pleroma.Web.base_url() %>">Homepage</a></h3> diff --git a/lib/pleroma/web/templates/twitter_api/util/password_reset_success.html.eex b/lib/pleroma/web/templates/twitter_api/util/password_reset_success.html.eex index c7dfcb6dd..f30ba3274 100644 --- a/lib/pleroma/web/templates/twitter_api/util/password_reset_success.html.eex +++ b/lib/pleroma/web/templates/twitter_api/util/password_reset_success.html.eex @@ -1 +1,2 @@ <h2>Password changed!</h2> +<h3><a href="<%= Pleroma.Web.base_url() %>">Homepage</a></h3> diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index b1e4c77e8..a8e3467c4 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -156,14 +156,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do |> send_resp(200, response) _ -> - vapid_public_key = - Keyword.get(Application.get_env(:web_push_encryption, :vapid_details), :public_key) + vapid_public_key = Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key) + + uploadlimit = %{ + uploadlimit: to_string(Keyword.get(instance, :upload_limit)), + avatarlimit: to_string(Keyword.get(instance, :avatar_upload_limit)), + backgroundlimit: to_string(Keyword.get(instance, :background_upload_limit)), + bannerlimit: to_string(Keyword.get(instance, :banner_upload_limit)) + } data = %{ name: Keyword.get(instance, :name), description: Keyword.get(instance, :description), server: Web.base_url(), textlimit: to_string(Keyword.get(instance, :limit)), + uploadlimit: uploadlimit, closed: if(Keyword.get(instance, :registrations_open), do: "0", else: "1"), private: if(Keyword.get(instance, :public, true), do: "0", else: "1"), vapidPublicKey: vapid_public_key diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 79ea48d86..1e764f24a 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -167,6 +167,25 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end end + def password_reset(nickname_or_email) do + with true <- is_binary(nickname_or_email), + %User{local: true} = user <- User.get_by_nickname_or_email(nickname_or_email), + {:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do + user + |> Pleroma.UserEmail.password_reset_email(token_record.token) + |> Pleroma.Mailer.deliver() + else + false -> + {:error, "bad user identifier"} + + %User{local: false} -> + {:error, "remote user"} + + nil -> + {:error, "unknown user"} + end + end + def get_by_id_or_nickname(id_or_nickname) do if !is_integer(id_or_nickname) && :error == Integer.parse(id_or_nickname) do Repo.get_by(User, nickname: id_or_nickname) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 786849aa3..38eff8191 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -1,5 +1,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do use Pleroma.Web, :controller + + import Pleroma.Web.ControllerHelper, only: [json_response: 3] + alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, ActivityView, NotificationView} alias Pleroma.Web.CommonAPI alias Pleroma.{Repo, Activity, Object, User, Notification} @@ -322,6 +325,14 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end end + def password_reset(conn, params) do + nickname_or_email = params["email"] || params["nickname"] + + with {:ok, _} <- TwitterAPI.password_reset(nickname_or_email) do + json_response(conn, :no_content, "") + end + end + def update_avatar(%{assigns: %{user: user}} = conn, params) do {:ok, object} = ActivityPub.upload(params, type: :avatar) change = Changeset.change(user, %{avatar: object.data}) diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index 83e8fb765..e5caed28f 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -190,6 +190,11 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do text = "#{user.nickname} favorited a status." + favorited_status = + if liked_activity, + do: render("activity.json", Map.merge(opts, %{activity: liked_activity})), + else: nil + %{ "id" => activity.id, "user" => UserView.render("show.json", %{user: user, for: opts[:for]}), @@ -199,6 +204,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do "is_post_verb" => false, "uri" => "tag:#{activity.data["id"]}:objectType=Favourite", "created_at" => created_at, + "favorited_status" => favorited_status, "in_reply_to_status_id" => liked_activity_id, "external_url" => activity.data["id"], "activity_type" => "like" |