First
[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)
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   # GET /api/v1/notifications
28   def index(conn, %{account_id: account_id} = params) do
29     case Pleroma.User.get_cached_by_id(account_id) do
30       %{ap_id: account_ap_id} ->
31         params =
32           params
33           |> Map.delete(:account_id)
34           |> Map.put(:account_ap_id, account_ap_id)
35
36         index(conn, params)
37
38       _ ->
39         conn
40         |> put_status(:not_found)
41         |> json(%{"error" => "Account is not found"})
42     end
43   end
44
45   @default_notification_types ~w{
46     mention
47     follow
48     follow_request
49     reblog
50     favourite
51     move
52     pleroma:emoji_reaction
53     poll
54     update
55   }
56   def index(%{assigns: %{user: user}} = conn, params) do
57     params =
58       Map.new(params, fn {k, v} -> {to_string(k), v} end)
59       |> Map.put_new("types", Map.get(params, :include_types, @default_notification_types))
60
61     notifications = MastodonAPI.get_notifications(user, params)
62
63     conn
64     |> add_link_headers(notifications)
65     |> render("index.json",
66       notifications: notifications,
67       for: user
68     )
69   end
70
71   # GET /api/v1/notifications/:id
72   def show(%{assigns: %{user: user}} = conn, %{id: id}) do
73     with {:ok, notification} <- Notification.get(user, id) do
74       render(conn, "show.json", notification: notification, for: user)
75     else
76       {:error, reason} ->
77         conn
78         |> put_status(:forbidden)
79         |> json(%{"error" => reason})
80     end
81   end
82
83   # POST /api/v1/notifications/clear
84   def clear(%{assigns: %{user: user}} = conn, _params) do
85     Notification.clear(user)
86     json(conn, %{})
87   end
88
89   # POST /api/v1/notifications/:id/dismiss
90
91   def dismiss(%{assigns: %{user: user}} = conn, %{id: id} = _params) do
92     with {:ok, _notif} <- Notification.dismiss(user, id) do
93       json(conn, %{})
94     else
95       {:error, reason} ->
96         conn
97         |> put_status(:forbidden)
98         |> json(%{"error" => reason})
99     end
100   end
101
102   # POST /api/v1/notifications/dismiss (deprecated)
103   def dismiss_via_body(%{body_params: params} = conn, _) do
104     dismiss(conn, params)
105   end
106
107   # DELETE /api/v1/notifications/destroy_multiple
108   def destroy_multiple(%{assigns: %{user: user}} = conn, %{ids: ids} = _params) do
109     Notification.destroy_multiple(user, ids)
110     json(conn, %{})
111   end
112 end