total rebase
[anni] / lib / pleroma / web / mastodon_api / controllers / notification_controller.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.NotificationController do
6   use Pleroma.Web, :controller
7
8   import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
9
10   alias Pleroma.Notification
11   alias Pleroma.Web.MastodonAPI.MastodonAPI
12   alias Pleroma.Web.Plugs.OAuthScopesPlug
13
14   @oauth_read_actions [:show, :index]
15
16   plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
17
18   plug(
19     OAuthScopesPlug,
20     %{scopes: ["read:notifications"]} when action in @oauth_read_actions
21   )
22
23   plug(OAuthScopesPlug, %{scopes: ["write:notifications"]} when action not in @oauth_read_actions)
24
25   defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.NotificationOperation
26
27   @default_notification_types ~w{
28       mention
29       follow
30       follow_request
31       reblog
32       favourite
33       move
34       pleroma:emoji_reaction
35       poll
36       update
37     }
38
39   # GET /api/v1/notifications
40   def index(%{private: %{open_api_spex: %{params: %{account_id: account_id} = params}}} = conn, _) do
41     case Pleroma.User.get_cached_by_id(account_id) do
42       %{ap_id: account_ap_id} ->
43         params =
44           params
45           |> Map.delete(:account_id)
46           |> Map.put(:account_ap_id, account_ap_id)
47
48         do_get_notifications(conn, params)
49
50       _ ->
51         conn
52         |> put_status(:not_found)
53         |> json(%{"error" => "Account is not found"})
54     end
55   end
56
57   def index(%{private: %{open_api_spex: %{params: params}}} = conn, _) do
58     do_get_notifications(conn, params)
59   end
60
61   defp do_get_notifications(%{assigns: %{user: user}} = conn, params) do
62     params =
63       Map.new(params, fn {k, v} -> {to_string(k), v} end)
64       |> Map.put_new("types", Map.get(params, :include_types, @default_notification_types))
65
66     notifications = MastodonAPI.get_notifications(user, params)
67
68     conn
69     |> add_link_headers(notifications)
70     |> render("index.json",
71       notifications: notifications,
72       for: user
73     )
74   end
75
76   # GET /api/v1/notifications/:id
77   def show(%{assigns: %{user: user}, private: %{open_api_spex: %{params: %{id: id}}}} = conn, _) do
78     with {:ok, notification} <- Notification.get(user, id) do
79       render(conn, "show.json", notification: notification, for: user)
80     else
81       {:error, reason} ->
82         conn
83         |> put_status(:forbidden)
84         |> json(%{"error" => reason})
85     end
86   end
87
88   # POST /api/v1/notifications/clear
89   def clear(%{assigns: %{user: user}} = conn, _params) do
90     Notification.clear(user)
91     json(conn, %{})
92   end
93
94   # POST /api/v1/notifications/:id/dismiss
95
96   def dismiss(%{private: %{open_api_spex: %{params: %{id: id}}}} = conn, _) do
97     do_dismiss(conn, id)
98   end
99
100   # POST /api/v1/notifications/dismiss (deprecated)
101   def dismiss_via_body(
102         %{private: %{open_api_spex: %{body_params: %{id: id}}}} = conn,
103         _
104       ) do
105     do_dismiss(conn, id)
106   end
107
108   defp do_dismiss(%{assigns: %{user: user}} = conn, notification_id) do
109     with {:ok, _notif} <- Notification.dismiss(user, notification_id) do
110       json(conn, %{})
111     else
112       {:error, reason} ->
113         conn
114         |> put_status(:forbidden)
115         |> json(%{"error" => reason})
116     end
117   end
118
119   # DELETE /api/v1/notifications/destroy_multiple
120   def destroy_multiple(
121         %{assigns: %{user: user}, private: %{open_api_spex: %{params: %{ids: ids}}}} = conn,
122         _
123       ) do
124     Notification.destroy_multiple(user, ids)
125     json(conn, %{})
126   end
127 end