Add Push notifications backend support
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
49
lib/mobilizon/users/push_subscription.ex
Normal file
49
lib/mobilizon/users/push_subscription.ex
Normal file
@@ -0,0 +1,49 @@
|
||||
defmodule Mobilizon.Users.PushSubscription do
|
||||
use Ecto.Schema
|
||||
alias Mobilizon.Users.User
|
||||
import Ecto.Changeset
|
||||
|
||||
schema "user_push_subscriptions" do
|
||||
field(:digest, :string)
|
||||
belongs_to(:user, User)
|
||||
|
||||
embeds_one :data, Data, on_replace: :delete do
|
||||
field(:endpoint, :string)
|
||||
|
||||
embeds_one :keys, Keys, on_replace: :delete do
|
||||
field(:auth, :string)
|
||||
field(:p256dh, :string)
|
||||
end
|
||||
end
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(push_subscription, attrs) do
|
||||
push_subscription
|
||||
|> cast(attrs, [:user_id])
|
||||
|> cast_embed(:data, with: &cast_data/2)
|
||||
|> put_change(:digest, compute_digest(attrs.data))
|
||||
|> validate_required([:digest, :user_id, :data])
|
||||
end
|
||||
|
||||
defp cast_data(schema, attrs) do
|
||||
schema
|
||||
|> cast(attrs, [:endpoint])
|
||||
|> cast_embed(:keys, with: &cast_keys/2)
|
||||
|> validate_required([:endpoint, :keys])
|
||||
end
|
||||
|
||||
defp cast_keys(schema, attrs) do
|
||||
schema
|
||||
|> cast(attrs, [:auth, :p256dh])
|
||||
|> validate_required([:auth, :p256dh])
|
||||
end
|
||||
|
||||
defp compute_digest(data) do
|
||||
:sha256
|
||||
|> :crypto.hash(data)
|
||||
|> Base.encode16()
|
||||
end
|
||||
end
|
||||
@@ -14,6 +14,8 @@ defmodule Mobilizon.Users.Setting do
|
||||
notification_before_event: boolean,
|
||||
notification_pending_participation: NotificationPendingNotificationDelay.t(),
|
||||
notification_pending_membership: NotificationPendingNotificationDelay.t(),
|
||||
group_notifications: NotificationPendingNotificationDelay.t(),
|
||||
last_notification_sent: DateTime.t(),
|
||||
user: User.t()
|
||||
}
|
||||
|
||||
@@ -25,7 +27,9 @@ defmodule Mobilizon.Users.Setting do
|
||||
:notification_each_week,
|
||||
:notification_before_event,
|
||||
:notification_pending_participation,
|
||||
:notification_pending_membership
|
||||
:notification_pending_membership,
|
||||
:group_notifications,
|
||||
:last_notification_sent
|
||||
]
|
||||
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
@@ -47,6 +51,9 @@ defmodule Mobilizon.Users.Setting do
|
||||
default: :one_day
|
||||
)
|
||||
|
||||
field(:group_notifications, NotificationPendingNotificationDelay, default: :one_day)
|
||||
field(:last_notification_sent, :utc_datetime)
|
||||
|
||||
embeds_one :location, Location, on_replace: :update, primary_key: false do
|
||||
field(:name, :string)
|
||||
field(:range, :integer)
|
||||
|
||||
@@ -13,7 +13,7 @@ defmodule Mobilizon.Users do
|
||||
alias Mobilizon.{Crypto, Events}
|
||||
alias Mobilizon.Events.FeedToken
|
||||
alias Mobilizon.Storage.{Page, Repo}
|
||||
alias Mobilizon.Users.{Setting, User}
|
||||
alias Mobilizon.Users.{PushSubscription, Setting, User}
|
||||
|
||||
defenum(UserRole, :user_role, [:administrator, :moderator, :user])
|
||||
|
||||
@@ -405,6 +405,80 @@ defmodule Mobilizon.Users do
|
||||
Setting.changeset(setting, %{})
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get a paginated list of all of a user's subscriptions
|
||||
"""
|
||||
@spec list_user_push_subscriptions(String.t() | integer(), integer() | nil, integer() | nil) ::
|
||||
Page.t()
|
||||
def list_user_push_subscriptions(user_id, page \\ nil, limit \\ nil) do
|
||||
PushSubscription
|
||||
|> where([p], p.user_id == ^user_id)
|
||||
|> preload([:user])
|
||||
|> Page.build_page(page, limit)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get a push subscription by their ID
|
||||
"""
|
||||
@spec get_push_subscription(String.t() | integer()) :: PushSubscription.t() | nil
|
||||
def get_push_subscription(push_subscription_id) do
|
||||
PushSubscription
|
||||
|> Repo.get(push_subscription_id)
|
||||
|> Repo.preload([:user])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a push subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_push_subscription(%{field: value})
|
||||
{:ok, %PushSubscription{}}
|
||||
|
||||
iex> create_push_subscription(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_push_subscription(attrs \\ %{}) do
|
||||
%PushSubscription{}
|
||||
|> PushSubscription.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates a push subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> update_push_subscription(push_subscription, %{field: new_value})
|
||||
{:ok, %PushSubscription{}}
|
||||
|
||||
iex> update_push_subscription(push_subscription, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_push_subscription(%PushSubscription{} = push_subscription, attrs) do
|
||||
push_subscription
|
||||
|> PushSubscription.changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a push subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_push_subscription(push_subscription)
|
||||
{:ok, %PushSubscription{}}
|
||||
|
||||
iex> delete_push_subscription(push_subscription)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_push_subscription(%PushSubscription{} = push_subscription) do
|
||||
Repo.delete(push_subscription)
|
||||
end
|
||||
|
||||
@spec user_by_email_query(String.t(), boolean | nil, boolean()) :: Ecto.Query.t()
|
||||
defp user_by_email_query(email, activated, unconfirmed) do
|
||||
User
|
||||
|
||||
Reference in New Issue
Block a user