Merge remote-tracking branch 'upstream/develop' into restrict-origin
[akkoma] / lib / pleroma / web / twitter_api / controllers / util_controller.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.TwitterAPI.UtilController do
6 use Pleroma.Web, :controller
7
8 require Logger
9
10 alias Pleroma.Config
11 alias Pleroma.Emoji
12 alias Pleroma.Healthcheck
13 alias Pleroma.Notification
14 alias Pleroma.Plugs.OAuthScopesPlug
15 alias Pleroma.User
16 alias Pleroma.Web.CommonAPI
17 alias Pleroma.Web.WebFinger
18
19 plug(Pleroma.Web.FederatingPlug when action == :remote_subscribe)
20
21 plug(
22 OAuthScopesPlug,
23 %{scopes: ["write:accounts"]}
24 when action in [
25 :change_email,
26 :change_password,
27 :delete_account,
28 :update_notificaton_settings,
29 :disable_account
30 ]
31 )
32
33 plug(OAuthScopesPlug, %{scopes: ["write:notifications"]} when action == :notifications_read)
34
35 def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do
36 with %User{} = user <- User.get_cached_by_nickname(nick),
37 avatar = User.avatar_url(user) do
38 conn
39 |> render("subscribe.html", %{nickname: nick, avatar: avatar, error: false})
40 else
41 _e ->
42 render(conn, "subscribe.html", %{
43 nickname: nick,
44 avatar: nil,
45 error: "Could not find user"
46 })
47 end
48 end
49
50 def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profile}}) do
51 with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile),
52 %User{ap_id: ap_id} <- User.get_cached_by_nickname(nick) do
53 conn
54 |> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id))
55 else
56 _e ->
57 render(conn, "subscribe.html", %{
58 nickname: nick,
59 avatar: nil,
60 error: "Something went wrong."
61 })
62 end
63 end
64
65 def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do
66 with {:ok, _} <- Notification.read_one(user, notification_id) do
67 json(conn, %{status: "success"})
68 else
69 {:error, message} ->
70 conn
71 |> put_resp_content_type("application/json")
72 |> send_resp(403, Jason.encode!(%{"error" => message}))
73 end
74 end
75
76 def frontend_configurations(conn, _params) do
77 config =
78 Config.get(:frontend_configurations, %{})
79 |> Enum.into(%{})
80
81 json(conn, config)
82 end
83
84 def emoji(conn, _params) do
85 emoji =
86 Enum.reduce(Emoji.get_all(), %{}, fn {code, %Emoji{file: file, tags: tags}}, acc ->
87 Map.put(acc, code, %{image_url: file, tags: tags})
88 end)
89
90 json(conn, emoji)
91 end
92
93 def update_notificaton_settings(%{assigns: %{user: user}} = conn, params) do
94 with {:ok, _} <- User.update_notification_settings(user, params) do
95 json(conn, %{status: "success"})
96 end
97 end
98
99 def change_password(%{assigns: %{user: user}} = conn, params) do
100 case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
101 {:ok, user} ->
102 with {:ok, _user} <-
103 User.reset_password(user, %{
104 password: params["new_password"],
105 password_confirmation: params["new_password_confirmation"]
106 }) do
107 json(conn, %{status: "success"})
108 else
109 {:error, changeset} ->
110 {_, {error, _}} = Enum.at(changeset.errors, 0)
111 json(conn, %{error: "New password #{error}."})
112
113 _ ->
114 json(conn, %{error: "Unable to change password."})
115 end
116
117 {:error, msg} ->
118 json(conn, %{error: msg})
119 end
120 end
121
122 def change_email(%{assigns: %{user: user}} = conn, params) do
123 case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
124 {:ok, user} ->
125 with {:ok, _user} <- User.change_email(user, params["email"]) do
126 json(conn, %{status: "success"})
127 else
128 {:error, changeset} ->
129 {_, {error, _}} = Enum.at(changeset.errors, 0)
130 json(conn, %{error: "Email #{error}."})
131
132 _ ->
133 json(conn, %{error: "Unable to change email."})
134 end
135
136 {:error, msg} ->
137 json(conn, %{error: msg})
138 end
139 end
140
141 def delete_account(%{assigns: %{user: user}} = conn, params) do
142 password = params["password"] || ""
143
144 case CommonAPI.Utils.confirm_current_password(user, password) do
145 {:ok, user} ->
146 User.delete(user)
147 json(conn, %{status: "success"})
148
149 {:error, msg} ->
150 json(conn, %{error: msg})
151 end
152 end
153
154 def disable_account(%{assigns: %{user: user}} = conn, params) do
155 case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
156 {:ok, user} ->
157 User.deactivate_async(user)
158 json(conn, %{status: "success"})
159
160 {:error, msg} ->
161 json(conn, %{error: msg})
162 end
163 end
164
165 def captcha(conn, _params) do
166 json(conn, Pleroma.Captcha.new())
167 end
168
169 def healthcheck(conn, _params) do
170 with true <- Config.get([:instance, :healthcheck]),
171 %{healthy: true} = info <- Healthcheck.system_info() do
172 json(conn, info)
173 else
174 %{healthy: false} = info ->
175 service_unavailable(conn, info)
176
177 _ ->
178 service_unavailable(conn, %{})
179 end
180 end
181
182 defp service_unavailable(conn, info) do
183 conn
184 |> put_status(:service_unavailable)
185 |> json(info)
186 end
187 end