diff --git a/lib/graphql/resolvers/user.ex b/lib/graphql/resolvers/user.ex index fb044ad18..3378cdc15 100644 --- a/lib/graphql/resolvers/user.ex +++ b/lib/graphql/resolvers/user.ex @@ -610,6 +610,28 @@ defmodule Mobilizon.GraphQL.Resolvers.User do end end + def unban_account(_parent, %{user_id: user_id}, %{ + context: %{ + current_user: %User{role: role}, + current_actor: %Actor{} = moderator_actor + } + }) + when is_moderator(role) do + with %User{disabled: true} = user <- Users.get_user(user_id), + {:ok, %User{} = updated_user} <- + Users.unban_user(user) do + Admin.log_action(moderator_actor, "unsuspend", user) + {:ok, updated_user} + else + %User{disabled: false} -> + {:error, dgettext("errors", "User already enabled")} + end + end + + def unban_account(_parent, _args, _resolution) do + {:error, dgettext("errors", "You need to be logged-in and moderator to unban an account")} + end + def delete_account(_parent, %{user_id: user_id}, %{ context: %{ current_user: %User{role: role}, diff --git a/lib/graphql/schema/user.ex b/lib/graphql/schema/user.ex index 863206dfe..942831f17 100644 --- a/lib/graphql/schema/user.ex +++ b/lib/graphql/schema/user.ex @@ -467,6 +467,13 @@ defmodule Mobilizon.GraphQL.Schema.UserType do resolve(&User.delete_account/3) end + @desc "Unban an account" + field :unban_account, :user do + arg(:user_id, :id, description: "The user's ID") + middleware(Rajska.QueryAuthorization, permit: :moderator, scope: false) + resolve(&User.unban_account/3) + end + @desc "Set user settings" field :set_user_settings, :user_settings do arg(:timezone, :timezone, description: "The timezone for this user") diff --git a/lib/mobilizon/users/users.ex b/lib/mobilizon/users/users.ex index 0a2b5e1c0..494ad4ff7 100644 --- a/lib/mobilizon/users/users.ex +++ b/lib/mobilizon/users/users.ex @@ -170,6 +170,15 @@ defmodule Mobilizon.Users do @delete_user_default_options [reserve_email: true] + @spec unban_user(User.t()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()} + def unban_user(%User{} = user) do + user + |> User.changeset(%{ + disabled: false + }) + |> Repo.update() + end + @doc """ Deletes an user. diff --git a/src/graphql/user.ts b/src/graphql/user.ts index 5a01ee38a..3cc328d95 100644 --- a/src/graphql/user.ts +++ b/src/graphql/user.ts @@ -92,6 +92,14 @@ export const DELETE_ACCOUNT_AS_MODERATOR = gql` } `; +export const UNBAN_ACCOUNT_AS_MODERATOR = gql` + mutation UnbanAccount($userId: ID) { + unbanAccount(userId: $userId) { + id + } + } +`; + export const CURRENT_USER_CLIENT = gql` query CurrentUserClient { currentUser @client { diff --git a/src/i18n/en_US.json b/src/i18n/en_US.json index 25eb7a710..2239db527 100644 --- a/src/i18n/en_US.json +++ b/src/i18n/en_US.json @@ -370,6 +370,7 @@ "Do not receive any mail": "Do not receive any mail", "Do you really want to ban the account \u00ab\u00a0{emailAccount}\u00a0\u00bb\u00a0?": "Do you really want to ban the account \u00ab\u00a0{emailAccount}\u00a0\u00bb\u00a0?", "Do you really want to ban this account? All of the user's profiles will be deleted.": "Do you really want to ban this account? All of the user's profiles will be deleted.", + "Do you really want to unban this account? The user will be able to log-in again.":"Do you really want to unban this account? The user will be able to log-in again.", "Do you really want to suspend this profile? All of the profiles content will be deleted.": "Do you really want to suspend this profile? All of the profiles content will be deleted.", "Do you wish to {create_event} or {explore_events}?": "Do you wish to {create_event} or {explore_events}?", "Do you wish to {create_group} or {explore_groups}?": "Do you wish to {create_group} or {explore_groups}?", @@ -1334,6 +1335,9 @@ "Unable to load event for participation. The error details are provided below:": "Unable to load event for participation. The error details are provided below:", "Unable to save your participation in this browser.": "Unable to save your participation in this browser.", "Unable to update the profile. The avatar picture may be too heavy.": "Unable to update the profile. The avatar picture may be too heavy.", + "Unban": "Unban", + "Unban the account": "Unban the account", + "Unban the account?": "Unban the account?", "Underline": "Underline", "Undo": "Undo", "Unfollow": "Unfollow", diff --git a/src/i18n/fr_FR.json b/src/i18n/fr_FR.json index a77226602..e597698f0 100644 --- a/src/i18n/fr_FR.json +++ b/src/i18n/fr_FR.json @@ -368,6 +368,7 @@ "Do not receive any mail": "Ne pas recevoir d'e-mail", "Do you really want to ban the account « {emailAccount} » ?": "Voulez-vous vraiment bannir le compte « {emailAccount} » ?", "Do you really want to ban this account? All of the user's profiles will be deleted.": "Voulez-vous vraiment bannir ce compte ? Tous les profils de cet·te utilisateur·ice seront supprimés.", + "Do you really want to unban this account? The user will be able to log-in again.":"Voulez-vous vraiment débannir ce compte ? L'utilisateur pourra à nouveau se connecter.", "Do you really want to suspend this profile? All of the profiles content will be deleted.": "Voulez-vous vraiment suspendre ce profil ? Tout le contenu du profil sera supprimé.", "Do you wish to {create_event} or {explore_events}?": "Voulez-vous {create_event} ou {explore_events} ?", "Do you wish to {create_group} or {explore_groups}?": "Voulez-vous {create_group} ou {explore_groups} ?", @@ -1341,6 +1342,9 @@ "Unable to load event for participation. The error details are provided below:": "Impossible de charger l'événement pour la participation. Les détails de l'erreur sont disponibles ci-dessous :", "Unable to save your participation in this browser.": "Échec de la sauvegarde de votre participation dans ce navigateur.", "Unable to update the profile. The avatar picture may be too heavy.": "Impossible de mettre à jour le profil. L'image d'avatar est probablement trop lourde.", + "Unban": "Débannir", + "Unban the account": "Débannir le compte", + "Unban the account?": "Débannir le compte?", "Underline": "Souligné", "Undo": "Annuler", "Unfollow": "Ne plus suivre", diff --git a/src/views/Admin/AdminUserProfile.vue b/src/views/Admin/AdminUserProfile.vue index 0e54cdc75..e643c8e41 100644 --- a/src/views/Admin/AdminUserProfile.vue +++ b/src/views/Admin/AdminUserProfile.vue @@ -188,12 +188,16 @@ t("Ban") }} -