diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mix/tasks/pleroma/instance.ex | 16 | ||||
-rw-r--r-- | lib/mix/tasks/pleroma/sample_config.eex | 2 | ||||
-rw-r--r-- | lib/pleroma/activity.ex | 15 | ||||
-rw-r--r-- | lib/pleroma/emails/user_email.ex | 26 | ||||
-rw-r--r-- | lib/pleroma/formatter.ex | 14 | ||||
-rw-r--r-- | lib/pleroma/html.ex | 10 | ||||
-rw-r--r-- | lib/pleroma/plugs/oauth_plug.ex | 28 | ||||
-rw-r--r-- | lib/pleroma/web/admin_api/admin_api_controller.ex | 13 | ||||
-rw-r--r-- | lib/pleroma/web/common_api/utils.ex | 10 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 69 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/push_subscription_view.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/status_view.ex | 23 | ||||
-rw-r--r-- | lib/pleroma/web/nodeinfo/nodeinfo_controller.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/web/push/push.ex | 120 | ||||
-rw-r--r-- | lib/pleroma/web/push/subscription.ex | 14 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/controllers/util_controller.ex | 14 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/views/activity_view.ex | 3 |
18 files changed, 259 insertions, 128 deletions
diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex index 3be856115..02e1ce27d 100644 --- a/lib/mix/tasks/pleroma/instance.ex +++ b/lib/mix/tasks/pleroma/instance.ex @@ -58,12 +58,15 @@ defmodule Mix.Tasks.Pleroma.Instance do proceed? = Enum.empty?(will_overwrite) or Keyword.get(options, :force, false) unless not proceed? do - domain = - Common.get_option( - options, - :domain, - "What domain will your instance use? (e.g pleroma.soykaf.com)" - ) + [domain, port | _] = + String.split( + Common.get_option( + options, + :domain, + "What domain will your instance use? (e.g pleroma.soykaf.com)" + ), + ":" + ) ++ [443] name = Common.get_option( @@ -104,6 +107,7 @@ defmodule Mix.Tasks.Pleroma.Instance do EEx.eval_file( "sample_config.eex" |> Path.expand(__DIR__), domain: domain, + port: port, email: email, name: name, dbhost: dbhost, diff --git a/lib/mix/tasks/pleroma/sample_config.eex b/lib/mix/tasks/pleroma/sample_config.eex index 0cd572797..740b9f8d1 100644 --- a/lib/mix/tasks/pleroma/sample_config.eex +++ b/lib/mix/tasks/pleroma/sample_config.eex @@ -6,7 +6,7 @@ use Mix.Config config :pleroma, Pleroma.Web.Endpoint, - url: [host: "<%= domain %>", scheme: "https", port: 443], + url: [host: "<%= domain %>", scheme: "https", port: <%= port %>], secret_key_base: "<%= secret %>" config :pleroma, :instance, diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index c065f3b6c..200addd6e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -3,6 +3,14 @@ defmodule Pleroma.Activity do alias Pleroma.{Repo, Activity, Notification} import Ecto.Query + # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 + @mastodon_notification_types %{ + "Create" => "mention", + "Follow" => "follow", + "Announce" => "reblog", + "Like" => "favourite" + } + schema "activities" do field(:data, :map) field(:local, :boolean, default: true) @@ -88,4 +96,11 @@ defmodule Pleroma.Activity do end def get_in_reply_to_activity(_), do: nil + + for {ap_type, type} <- @mastodon_notification_types do + def mastodon_notification_type(%Activity{data: %{"type" => unquote(ap_type)}}), + do: unquote(type) + end + + def mastodon_notification_type(%Activity{}), do: nil end diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex index 9cdf002f3..7e3e9b020 100644 --- a/lib/pleroma/emails/user_email.ex +++ b/lib/pleroma/emails/user_email.ex @@ -37,4 +37,30 @@ defmodule Pleroma.UserEmail do |> subject("Password reset") |> html_body(html_body) end + + def user_invitation_email( + user, + %Pleroma.UserInviteToken{} = user_invite_token, + to_email, + to_name \\ nil + ) do + registration_url = + Router.Helpers.redirect_url( + Endpoint, + :registration_page, + user_invite_token.token + ) + + html_body = """ + <h3>You are invited to #{instance_name()}</h3> + <p>#{user.name} invites you to join #{instance_name()}, an instance of Pleroma federated social networking platform.</p> + <p>Click the following link to register: <a href="#{registration_url}">accept invitation</a>.</p> + """ + + new() + |> to(recipient(to_email, to_name)) + |> from(sender()) + |> subject("Invitation to #{instance_name()}") + |> html_body(html_body) + end end diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 133683794..46d0d926a 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -5,6 +5,8 @@ defmodule Pleroma.Formatter do alias Pleroma.Emoji @tag_regex ~r/\#\w+/u + @markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/ + def parse_tags(text, data \\ %{}) do Regex.scan(@tag_regex, text) |> Enum.map(fn ["#" <> tag = full_tag] -> {full_tag, String.downcase(tag)} end) @@ -76,6 +78,18 @@ defmodule Pleroma.Formatter do |> Enum.join("") end + @doc """ + Escapes a special characters in mention names. + """ + @spec mentions_escape(String.t(), list({String.t(), any()})) :: String.t() + def mentions_escape(text, mentions) do + mentions + |> Enum.reduce(text, fn {name, _}, acc -> + escape_name = String.replace(name, @markdown_characters_regex, "\\\\\\1") + String.replace(acc, name, escape_name) + end) + end + @doc "changes scheme:... urls to html links" def add_links({subs, text}) do links = diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index 8a0333461..583f05aeb 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -17,15 +17,9 @@ defmodule Pleroma.HTML do end) end - def filter_tags(html, scrubber) do - html |> Scrubber.scrub(scrubber) - end - + def filter_tags(html, scrubber), do: Scrubber.scrub(html, scrubber) def filter_tags(html), do: filter_tags(html, nil) - - def strip_tags(html) do - html |> Scrubber.scrub(Scrubber.StripTags) - end + def strip_tags(html), do: Scrubber.scrub(html, Scrubber.StripTags) end defmodule Pleroma.HTML.Scrubber.TwitterText do diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex index 8b99a74d1..13c914c1b 100644 --- a/lib/pleroma/plugs/oauth_plug.ex +++ b/lib/pleroma/plugs/oauth_plug.ex @@ -15,10 +15,10 @@ defmodule Pleroma.Plugs.OAuthPlug do def call(%{assigns: %{user: %User{}}} = conn, _), do: conn def call(conn, _) do - with {:ok, token} <- fetch_token(conn), - {:ok, user} <- fetch_user(token) do + with {:ok, token_str} <- fetch_token_str(conn), + {:ok, user, token_record} <- fetch_user_and_token(token_str) do conn - |> assign(:token, token) + |> assign(:token, token_record) |> assign(:user, user) else _ -> conn @@ -27,12 +27,12 @@ defmodule Pleroma.Plugs.OAuthPlug do # Gets user by token # - @spec fetch_user(String.t()) :: {:ok, User.t()} | nil - defp fetch_user(token) do + @spec fetch_user_and_token(String.t()) :: {:ok, User.t(), Token.t()} | nil + defp fetch_user_and_token(token) do query = from(q in Token, where: q.token == ^token, preload: [:user]) - with %Token{user: %{info: %{deactivated: false} = _} = user} <- Repo.one(query) do - {:ok, user} + with %Token{user: %{info: %{deactivated: false} = _} = user} = token_record <- Repo.one(query) do + {:ok, user, token_record} end end @@ -48,23 +48,23 @@ defmodule Pleroma.Plugs.OAuthPlug do # Gets token from headers # - @spec fetch_token(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()} - defp fetch_token(%Plug.Conn{} = conn) do + @spec fetch_token_str(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()} + defp fetch_token_str(%Plug.Conn{} = conn) do headers = get_req_header(conn, "authorization") - with :no_token_found <- fetch_token(headers), + with :no_token_found <- fetch_token_str(headers), do: fetch_token_from_session(conn) end - @spec fetch_token(Keyword.t()) :: :no_token_found | {:ok, String.t()} - defp fetch_token([]), do: :no_token_found + @spec fetch_token_str(Keyword.t()) :: :no_token_found | {:ok, String.t()} + defp fetch_token_str([]), do: :no_token_found - defp fetch_token([token | tail]) do + defp fetch_token_str([token | tail]) do trimmed_token = String.trim(token) case Regex.run(@realm_reg, trimmed_token) do [_, match] -> {:ok, String.trim(match)} - _ -> fetch_token(tail) + _ -> fetch_token_str(tail) end end end diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 06c3c7c81..4d73cf219 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -147,6 +147,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do end end + @doc "Sends registration invite via email" + def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do + with true <- + Pleroma.Config.get([:instance, :invites_enabled]) && + !Pleroma.Config.get([:instance, :registrations_open]), + {:ok, invite_token} <- Pleroma.UserInviteToken.create_token(), + email <- + Pleroma.UserEmail.user_invitation_email(user, invite_token, email, params["name"]), + {:ok, _} <- Pleroma.Mailer.deliver(email) do + json_response(conn, :no_content, "") + end + end + @doc "Get a account registeration invite token (base64 string)" def get_invite_token(conn, _params) do {:ok, token} = Pleroma.UserInviteToken.create_token() diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index ce0926b99..142283684 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -112,6 +112,9 @@ defmodule Pleroma.Web.CommonAPI.Utils do Enum.join([text | attachment_text], "<br>") end + @doc """ + Formatting text to plain text. + """ def format_input(text, mentions, tags, "text/plain") do text |> Formatter.html_escape("text/plain") @@ -123,6 +126,9 @@ defmodule Pleroma.Web.CommonAPI.Utils do |> Formatter.finalize() end + @doc """ + Formatting text to html. + """ def format_input(text, mentions, _tags, "text/html") do text |> Formatter.html_escape("text/html") @@ -132,8 +138,12 @@ defmodule Pleroma.Web.CommonAPI.Utils do |> Formatter.finalize() end + @doc """ + Formatting text to markdown. + """ def format_input(text, mentions, tags, "text/markdown") do text + |> Formatter.mentions_escape(mentions) |> Earmark.as_html!() |> Formatter.html_escape("text/html") |> String.replace(~r/\r?\n/, "") diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 5c8602322..0414d73d8 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -1055,52 +1055,37 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do actor = User.get_cached_by_ap_id(activity.data["actor"]) + parent_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + mastodon_type = Activity.mastodon_notification_type(activity) - created_at = - NaiveDateTime.to_iso8601(created_at) - |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false) - - id = id |> to_string + response = %{ + id: to_string(id), + type: mastodon_type, + created_at: CommonAPI.Utils.to_masto_date(created_at), + account: AccountView.render("account.json", %{user: actor, for: user}) + } - case activity.data["type"] do - "Create" -> - %{ - id: id, - type: "mention", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}), + case mastodon_type do + "mention" -> + response + |> Map.merge(%{ status: StatusView.render("status.json", %{activity: activity, for: user}) - } + }) - "Like" -> - liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + "favourite" -> + response + |> Map.merge(%{ + status: StatusView.render("status.json", %{activity: parent_activity, for: user}) + }) - %{ - id: id, - type: "favourite", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}), - status: StatusView.render("status.json", %{activity: liked_activity, for: user}) - } + "reblog" -> + response + |> Map.merge(%{ + status: StatusView.render("status.json", %{activity: parent_activity, for: user}) + }) - "Announce" -> - announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) - - %{ - id: id, - type: "reblog", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}), - status: StatusView.render("status.json", %{activity: announced_activity, for: user}) - } - - "Follow" -> - %{ - id: id, - type: "follow", - created_at: created_at, - account: AccountView.render("account.json", %{user: actor, for: user}) - } + "follow" -> + response _ -> nil @@ -1167,6 +1152,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def create_push_subscription(%{assigns: %{user: user, token: token}} = conn, params) do + true = Pleroma.Web.Push.enabled() Pleroma.Web.Push.Subscription.delete_if_exists(user, token) {:ok, subscription} = Pleroma.Web.Push.Subscription.create(user, token, params) view = PushSubscriptionView.render("push_subscription.json", subscription: subscription) @@ -1174,6 +1160,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def get_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do + true = Pleroma.Web.Push.enabled() subscription = Pleroma.Web.Push.Subscription.get(user, token) view = PushSubscriptionView.render("push_subscription.json", subscription: subscription) json(conn, view) @@ -1183,12 +1170,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do %{assigns: %{user: user, token: token}} = conn, params ) do + true = Pleroma.Web.Push.enabled() {:ok, subscription} = Pleroma.Web.Push.Subscription.update(user, token, params) view = PushSubscriptionView.render("push_subscription.json", subscription: subscription) json(conn, view) end def delete_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do + true = Pleroma.Web.Push.enabled() {:ok, _response} = Pleroma.Web.Push.Subscription.delete(user, token) json(conn, %{}) end diff --git a/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex b/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex index c8b95d14c..67e86294e 100644 --- a/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex +++ b/lib/pleroma/web/mastodon_api/views/push_subscription_view.ex @@ -5,7 +5,12 @@ defmodule Pleroma.Web.MastodonAPI.PushSubscriptionView do %{ id: to_string(subscription.id), endpoint: subscription.endpoint, - alerts: Map.get(subscription.data, "alerts") + alerts: Map.get(subscription.data, "alerts"), + server_key: server_key() } end + + defp server_key do + Keyword.get(Application.get_env(:web_push_encryption, :vapid_details), :public_key) + end end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index c3c735d5d..46c559e3a 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -140,7 +140,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do visibility: get_visibility(object), media_attachments: attachments |> Enum.take(4), mentions: mentions, - tags: tags, + tags: build_tags(tags), application: %{ name: "Web", website: nil @@ -235,6 +235,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do def render_content(object), do: object["content"] || "" @doc """ + Builds a dictionary tags. + + ## Examples + + iex> Pleroma.Web.MastodonAPI.StatusView.build_tags(["fediverse", "nextcloud"]) + [{"name": "fediverse", "url": "/tag/fediverse"}, + {"name": "nextcloud", "url": "/tag/nextcloud"}] + + """ + @spec build_tags(list(any())) :: list(map()) + def build_tags(object_tags) when is_list(object_tags) do + object_tags = for tag when is_binary(tag) <- object_tags, do: tag + + Enum.reduce(object_tags, [], fn tag, tags -> + tags ++ [%{name: tag, url: "/tag/#{tag}"}] + end) + end + + def build_tags(_), do: [] + + @doc """ Builds list emojis. Arguments: `nil` or list tuple of name and url. diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 277dc6ba1..44c11f40a 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -132,6 +132,7 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do banner: Keyword.get(instance, :banner_upload_limit), background: Keyword.get(instance, :background_upload_limit) }, + invitesEnabled: Keyword.get(instance, :invites_enabled, false), features: features } } diff --git a/lib/pleroma/web/push/push.ex b/lib/pleroma/web/push/push.ex index 5a873ec19..477943450 100644 --- a/lib/pleroma/web/push/push.ex +++ b/lib/pleroma/web/push/push.ex @@ -9,67 +9,99 @@ defmodule Pleroma.Web.Push do @types ["Create", "Follow", "Announce", "Like"] - @gcm_api_key nil - def start_link() do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) end - def init(:ok) do - case Application.get_env(:web_push_encryption, :vapid_details) do - nil -> - Logger.warn( - "VAPID key pair is not found. Please, add VAPID configuration to config. Run `mix web_push.gen.keypair` mix task to create a key pair" - ) - - :ignore + def vapid_config() do + Application.get_env(:web_push_encryption, :vapid_details, []) + end - _ -> - {:ok, %{}} + def enabled() do + case vapid_config() do + [] -> false + list when is_list(list) -> true + _ -> false end end def send(notification) do - if Application.get_env(:web_push_encryption, :vapid_details) do + if enabled() do GenServer.cast(Pleroma.Web.Push, {:send, notification}) end end + def init(:ok) do + if !enabled() do + Logger.warn(""" + VAPID key pair is not found. If you wish to enabled web push, please run + + mix web_push.gen.keypair + + and add the resulting output to your configuration file. + """) + + :ignore + else + {:ok, nil} + end + end + def handle_cast( {:send, %{activity: %{data: %{"type" => type}}, user_id: user_id} = notification}, state ) when type in @types do actor = User.get_cached_by_ap_id(notification.activity.data["actor"]) - body = notification |> format(actor) |> Jason.encode!() + + type = Pleroma.Activity.mastodon_notification_type(notification.activity) Subscription |> where(user_id: ^user_id) + |> preload(:token) |> Repo.all() - |> Enum.each(fn record -> - subscription = %{ + |> Enum.filter(fn subscription -> + get_in(subscription.data, ["alerts", type]) || false + end) + |> Enum.each(fn subscription -> + sub = %{ keys: %{ - p256dh: record.key_p256dh, - auth: record.key_auth + p256dh: subscription.key_p256dh, + auth: subscription.key_auth }, - endpoint: record.endpoint + endpoint: subscription.endpoint } - case WebPushEncryption.send_web_push(body, subscription, @gcm_api_key) do + body = + Jason.encode!(%{ + title: format_title(notification), + access_token: subscription.token.token, + body: format_body(notification, actor), + notification_id: notification.id, + notification_type: type, + icon: User.avatar_url(actor), + preferred_locale: "en" + }) + + case WebPushEncryption.send_web_push( + body, + sub, + Application.get_env(:web_push_encryption, :gcm_api_key) + ) do {:ok, %{status_code: code}} when 400 <= code and code < 500 -> Logger.debug("Removing subscription record") - Repo.delete!(record) + Repo.delete!(subscription) :ok {:ok, %{status_code: code}} when 200 <= code and code < 300 -> :ok {:ok, %{status_code: code}} -> - Logger.error("Web Push Nonification failed with code: #{code}") + Logger.error("Web Push Notification failed with code: #{code}") :error _ -> - Logger.error("Web Push Nonification failed with unknown error") + Logger.error("Web Push Notification failed with unknown error") :error end end) @@ -82,35 +114,21 @@ defmodule Pleroma.Web.Push do {:noreply, state} end - def format(%{activity: %{data: %{"type" => "Create"}}}, actor) do - %{ - title: "New Mention", - body: "@#{actor.nickname} has mentiond you", - icon: User.avatar_url(actor) - } - end - - def format(%{activity: %{data: %{"type" => "Follow"}}}, actor) do - %{ - title: "New Follower", - body: "@#{actor.nickname} has followed you", - icon: User.avatar_url(actor) - } - end - - def format(%{activity: %{data: %{"type" => "Announce"}}}, actor) do - %{ - title: "New Announce", - body: "@#{actor.nickname} has announced your post", - icon: User.avatar_url(actor) - } + defp format_title(%{activity: %{data: %{"type" => type}}}) do + case type do + "Create" -> "New Mention" + "Follow" -> "New Follower" + "Announce" -> "New Repeat" + "Like" -> "New Favorite" + end end - def format(%{activity: %{data: %{"type" => "Like"}}}, actor) do - %{ - title: "New Like", - body: "@#{actor.nickname} has liked your post", - icon: User.avatar_url(actor) - } + defp format_body(%{activity: %{data: %{"type" => type}}}, actor) do + case type do + "Create" -> "@#{actor.nickname} has mentioned you" + "Follow" -> "@#{actor.nickname} has followed you" + "Announce" -> "@#{actor.nickname} has repeated your post" + "Like" -> "@#{actor.nickname} has favorited your post" + end end end diff --git a/lib/pleroma/web/push/subscription.ex b/lib/pleroma/web/push/subscription.ex index cfab7a98e..1ad405daf 100644 --- a/lib/pleroma/web/push/subscription.ex +++ b/lib/pleroma/web/push/subscription.ex @@ -37,8 +37,8 @@ defmodule Pleroma.Web.Push.Subscription do user_id: user.id, token_id: token.id, endpoint: endpoint, - key_auth: key_auth, - key_p256dh: key_p256dh, + key_auth: ensure_base64_urlsafe(key_auth), + key_p256dh: ensure_base64_urlsafe(key_p256dh), data: alerts(params) }) end @@ -63,4 +63,14 @@ defmodule Pleroma.Web.Push.Subscription do sub -> Repo.delete(sub) end end + + # Some webpush clients (e.g. iOS Toot!) use an non urlsafe base64 as an encoding for the key. + # However, the web push rfs specify to use base64 urlsafe, and the `web_push_encryption` library we use + # requires the key to be properly encoded. So we just convert base64 to urlsafe base64. + defp ensure_base64_urlsafe(string) do + string + |> String.replace("+", "-") + |> String.replace("/", "_") + |> String.replace("=", "") + end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 6253a28db..daff3362c 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -117,6 +117,8 @@ defmodule Pleroma.Web.Router do delete("/relay", AdminAPIController, :relay_unfollow) get("/invite_token", AdminAPIController, :get_invite_token) + post("/email_invite", AdminAPIController, :email_invite) + get("/password_reset", AdminAPIController, :get_password_reset) end diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index b1e4c77e8..2f2b69623 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -156,17 +156,25 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do |> send_resp(200, response) _ -> - vapid_public_key = - Keyword.get(Application.get_env(:web_push_encryption, :vapid_details), :public_key) + vapid_public_key = Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key) + + uploadlimit = %{ + uploadlimit: to_string(Keyword.get(instance, :upload_limit)), + avatarlimit: to_string(Keyword.get(instance, :avatar_upload_limit)), + backgroundlimit: to_string(Keyword.get(instance, :background_upload_limit)), + bannerlimit: to_string(Keyword.get(instance, :banner_upload_limit)) + } data = %{ name: Keyword.get(instance, :name), description: Keyword.get(instance, :description), server: Web.base_url(), textlimit: to_string(Keyword.get(instance, :limit)), + uploadlimit: uploadlimit, closed: if(Keyword.get(instance, :registrations_open), do: "0", else: "1"), private: if(Keyword.get(instance, :public, true), do: "0", else: "1"), - vapidPublicKey: vapid_public_key + vapidPublicKey: vapid_public_key, + invitesEnabled: if(Keyword.get(instance, :invites_enabled, false), do: "1", else: "0") } pleroma_fe = %{ diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index e4d364118..0699bf1da 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -240,7 +240,8 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do {summary, content} = render_content(object) html = - HTML.filter_tags(content, User.html_filter_policy(opts[:for])) + content + |> HTML.filter_tags(User.html_filter_policy(opts[:for])) |> Formatter.emojify(object["emoji"]) reply_parent = Activity.get_in_reply_to_activity(activity) |