From 43fb03be5a8968c1df23938ed4f5a93825ab476c Mon Sep 17 00:00:00 2001 From: eugenijm Date: Fri, 15 Mar 2019 20:06:28 +0300 Subject: [PATCH] Allow to mark a single notification as read --- docs/Pleroma-API.md | 8 +++++++ lib/pleroma/notification.ex | 14 ++++++++++++ lib/pleroma/web/router.ex | 6 +++++ .../controllers/util_controller.ex | 12 ++++++++++ test/web/twitter_api/util_controller_test.exs | 22 +++++++++++++++++++ 5 files changed, 62 insertions(+) diff --git a/docs/Pleroma-API.md b/docs/Pleroma-API.md index 379d3dbed..478c9d874 100644 --- a/docs/Pleroma-API.md +++ b/docs/Pleroma-API.md @@ -108,3 +108,11 @@ See [Admin-API](Admin-API.md) * Response: JSON string. Returns the user flavour or the default one. * Example response: "glitch" * Note: This is intended to be used only by mastofe + +## `/api/pleroma/notifications/read` +### Mark a single notification as read +* Method `POST` +* Authentication: required +* Params: + * `id`: notifications's id +* Response: JSON. Returns `{"status": "success"}` if the reading was successful, otherwise returns `{"error": "error_msg"}` diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index fe8181d8b..765191275 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Notification do alias Pleroma.Web.CommonAPI.Utils import Ecto.Query + import Ecto.Changeset schema "notifications" do field(:seen, :boolean, default: false) @@ -22,6 +23,11 @@ defmodule Pleroma.Notification do timestamps() end + def changeset(%Notification{} = notification, attrs) do + notification + |> cast(attrs, [:seen]) + end + # TODO: Make generic and unify (see activity_pub.ex) defp restrict_max(query, %{"max_id" => max_id}) do from(activity in query, where: activity.id < ^max_id) @@ -68,6 +74,14 @@ def set_read_up_to(%{id: user_id} = _user, id) do Repo.update_all(query, []) end + def read_one(%User{} = user, notification_id) do + with {:ok, %Notification{} = notification} <- get(user, notification_id) do + notification + |> changeset(%{seen: true}) + |> Repo.update() + end + end + def get(%{id: user_id} = _user, id) do query = from( diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index c56e4a421..befd382ba 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -190,6 +190,12 @@ defmodule Pleroma.Web.Router do post("/blocks_import", UtilController, :blocks_import) post("/follow_import", UtilController, :follow_import) end + + scope [] do + pipe_through(:oauth_read) + + post("/notifications/read", UtilController, :notifications_read) + end end scope "/oauth", Pleroma.Web.OAuth do diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 8ed02a93f..320ec778c 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -9,6 +9,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do alias Comeonin.Pbkdf2 alias Pleroma.Emoji + alias Pleroma.Notification alias Pleroma.PasswordResetToken alias Pleroma.Repo alias Pleroma.User @@ -142,6 +143,17 @@ def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id} end end + def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do + with {:ok, _} <- Notification.read_one(user, notification_id) do + json(conn, %{status: "success"}) + else + {:error, message} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(403, Jason.encode!(%{"error" => message})) + end + end + def config(conn, _params) do instance = Pleroma.Config.get(:instance) instance_fe = Pleroma.Config.get(:fe) diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs index fc762ab18..6e8a25056 100644 --- a/test/web/twitter_api/util_controller_test.exs +++ b/test/web/twitter_api/util_controller_test.exs @@ -1,6 +1,9 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do use Pleroma.Web.ConnCase + alias Pleroma.Notification + alias Pleroma.Repo + alias Pleroma.Web.CommonAPI import Pleroma.Factory describe "POST /api/pleroma/follow_import" do @@ -52,6 +55,25 @@ test "it returns HTTP 200", %{conn: conn} do end end + describe "POST /api/pleroma/notifications/read" do + test "it marks a single notification as read", %{conn: conn} do + user1 = insert(:user) + user2 = insert(:user) + {:ok, activity1} = CommonAPI.post(user2, %{"status" => "hi @#{user1.nickname}"}) + {:ok, activity2} = CommonAPI.post(user2, %{"status" => "hi @#{user1.nickname}"}) + {:ok, [notification1]} = Notification.create_notifications(activity1) + {:ok, [notification2]} = Notification.create_notifications(activity2) + + conn + |> assign(:user, user1) + |> post("/api/pleroma/notifications/read", %{"id" => "#{notification1.id}"}) + |> json_response(:ok) + + assert Repo.get(Notification, notification1.id).seen + refute Repo.get(Notification, notification2.id).seen + end + end + describe "GET /api/statusnet/config.json" do test "it returns the managed config", %{conn: conn} do Pleroma.Config.put([:instance, :managed_config], false)