Fix creating discussion with title containing only spaces

Also sanitize first comment

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-03-24 15:47:03 +01:00
parent 48f52ba4fd
commit e6189390ac
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
4 changed files with 37 additions and 5 deletions

View File

@ -3,7 +3,11 @@
<h1>{{ $t("Create a discussion") }}</h1> <h1>{{ $t("Create a discussion") }}</h1>
<form @submit.prevent="createDiscussion"> <form @submit.prevent="createDiscussion">
<b-field :label="$t('Title')"> <b-field
:label="$t('Title')"
:message="errors.title"
:type="errors.title ? 'is-danger' : undefined"
>
<b-input aria-required="true" required v-model="discussion.title" /> <b-input aria-required="true" required v-model="discussion.title" />
</b-field> </b-field>
@ -64,7 +68,10 @@ export default class CreateDiscussion extends Vue {
discussion = { title: "", text: "" }; discussion = { title: "", text: "" };
errors = { title: "" };
async createDiscussion(): Promise<void> { async createDiscussion(): Promise<void> {
this.errors = { title: "" };
try { try {
if (!this.group.id || !this.currentActor.id) return; if (!this.group.id || !this.currentActor.id) return;
const { data } = await this.$apollo.mutate({ const { data } = await this.$apollo.mutate({
@ -86,7 +93,11 @@ export default class CreateDiscussion extends Vue {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
if (error.graphQLErrors && error.graphQLErrors.length > 0) { if (error.graphQLErrors && error.graphQLErrors.length > 0) {
this.$notifier.error(error.graphQLErrors[0].message); if (error.graphQLErrors[0].field == "title") {
this.errors.title = error.graphQLErrors[0].message;
} else {
this.$notifier.error(error.graphQLErrors[0].message);
}
} }
} }
} }

View File

@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
alias Mobilizon.Federation.ActivityPub.Audience alias Mobilizon.Federation.ActivityPub.Audience
alias Mobilizon.Federation.ActivityPub.Types.Entity alias Mobilizon.Federation.ActivityPub.Types.Entity
alias Mobilizon.Federation.ActivityStream.Convertible alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
alias Mobilizon.Service.Activity.Discussion, as: DiscussionActivity alias Mobilizon.Service.Activity.Discussion, as: DiscussionActivity
alias Mobilizon.Web.Endpoint alias Mobilizon.Web.Endpoint
import Mobilizon.Federation.ActivityPub.Utils, only: [make_create_data: 2, make_update_data: 2] import Mobilizon.Federation.ActivityPub.Utils, only: [make_create_data: 2, make_update_data: 2]
@ -17,7 +18,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
@impl Entity @impl Entity
@spec create(map(), map()) :: {:ok, map()} @spec create(map(), map()) :: {:ok, map()}
def create(%{discussion_id: discussion_id} = args, additional) when not is_nil(discussion_id) do def create(%{discussion_id: discussion_id} = args, additional) when not is_nil(discussion_id) do
with %Discussion{} = discussion <- Discussions.get_discussion(discussion_id), with args <- prepare_args(args),
%Discussion{} = discussion <- Discussions.get_discussion(discussion_id),
{:ok, %Discussion{last_comment_id: last_comment_id} = discussion} <- {:ok, %Discussion{last_comment_id: last_comment_id} = discussion} <-
Discussions.reply_to_discussion(discussion, args), Discussions.reply_to_discussion(discussion, args),
{:ok, _} <- {:ok, _} <-
@ -39,7 +41,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
@impl Entity @impl Entity
@spec create(map(), map()) :: {:ok, map()} @spec create(map(), map()) :: {:ok, map()}
def create(args, additional) do def create(args, additional) do
with {:ok, %Discussion{} = discussion} <- with args <- prepare_args(args),
{:ok, %Discussion{} = discussion} <-
Discussions.create_discussion(args), Discussions.create_discussion(args),
{:ok, _} <- {:ok, _} <-
DiscussionActivity.insert_activity(discussion, subject: "discussion_created"), DiscussionActivity.insert_activity(discussion, subject: "discussion_created"),
@ -118,4 +121,18 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
:ok :ok
end end
defp prepare_args(args) do
{text, _mentions, _tags} =
APIUtils.make_content_html(
args |> Map.get(:text, "") |> String.trim(),
# Can't put additional tags on a comment
[],
"text/html"
)
args
|> Map.update(:title, "", &String.trim/1)
|> Map.put(:text, text)
end
end end

View File

@ -104,6 +104,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
}) do }) do
{:ok, discussion} {:ok, discussion}
else else
{:error, :discussion, err, _} ->
{:error, err}
{:member, false} -> {:member, false} ->
{:error, :unauthorized} {:error, :unauthorized}
end end

View File

@ -28,6 +28,7 @@ defmodule Mobilizon.Discussions.Discussion do
alias Mobilizon.Discussions.Discussion.TitleSlug alias Mobilizon.Discussions.Discussion.TitleSlug
alias Mobilizon.Web.Endpoint alias Mobilizon.Web.Endpoint
alias Mobilizon.Web.Router.Helpers, as: Routes alias Mobilizon.Web.Router.Helpers, as: Routes
import Mobilizon.Web.Gettext, only: [dgettext: 2]
@type t :: %__MODULE__{ @type t :: %__MODULE__{
creator: Actor.t(), creator: Actor.t(),
@ -63,7 +64,7 @@ defmodule Mobilizon.Discussions.Discussion do
discussion discussion
|> cast(attrs, @attrs) |> cast(attrs, @attrs)
|> maybe_generate_id() |> maybe_generate_id()
|> validate_required([:title, :id]) |> validate_required([:title, :id], message: dgettext("errors", "can't be blank"))
|> TitleSlug.maybe_generate_slug() |> TitleSlug.maybe_generate_slug()
|> TitleSlug.unique_constraint() |> TitleSlug.unique_constraint()
|> maybe_generate_url() |> maybe_generate_url()