diff --git a/config/config.exs b/config/config.exs index cb708b25e..97bf5c466 100644 --- a/config/config.exs +++ b/config/config.exs @@ -12,7 +12,7 @@ config :mobilizon, config :mobilizon, :instance, name: System.get_env("MOBILIZON_INSTANCE_NAME") || "Localhost", version: "1.0.0-dev", - registrations_open: true + registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN") || true config :mime, :types, %{ "application/activity+json" => ["activity-json"], diff --git a/js/src/graphql/config.ts b/js/src/graphql/config.ts new file mode 100644 index 000000000..07a16aba0 --- /dev/null +++ b/js/src/graphql/config.ts @@ -0,0 +1,40 @@ +import gql from 'graphql-tag'; + +export const CREATE_USER = gql` +mutation CreateUser($email: String!, $password: String!) { + createUser(email: $email, password: $password) { + email, + confirmationSentAt + } +} +`; + +export const VALIDATE_USER = gql` +mutation ValidateUser($token: String!) { + validateUser(token: $token) { + token, + user { + id, + email, + defaultActor { + id + } + } + } +} +`; + +export const CURRENT_USER_CLIENT = gql` +query { + currentUser @client { + id, + email + } +} +`; + +export const UPDATE_CURRENT_USER_CLIENT = gql` +mutation UpdateCurrentUser($id: Int!, $email: String!) { + updateCurrentUser(id: $id, email: $email) @client +} +`; diff --git a/js/src/types/config.model.ts b/js/src/types/config.model.ts new file mode 100644 index 000000000..d3d3335e8 --- /dev/null +++ b/js/src/types/config.model.ts @@ -0,0 +1,7 @@ +import { ICurrentUser } from '@/types/current-user.model'; + +export interface ILogin { + user: ICurrentUser, + + token: string, +} diff --git a/lib/mobilizon/common-config.ex b/lib/mobilizon/common-config.ex new file mode 100644 index 000000000..d713c0187 --- /dev/null +++ b/lib/mobilizon/common-config.ex @@ -0,0 +1,7 @@ +defmodule Mobilizon.CommonConfig do + def registrations_open?(), do: instance_config() |> get_in([:registrations_open]) + + def instance_name(), do: instance_config() |> get_in([:name]) + + defp instance_config(), do: Application.get_env(:mobilizon, :instance) +end diff --git a/lib/mobilizon/users/user.ex b/lib/mobilizon/users/user.ex index d1bdae752..cd31a29f4 100644 --- a/lib/mobilizon/users/user.ex +++ b/lib/mobilizon/users/user.ex @@ -146,13 +146,8 @@ defmodule Mobilizon.Users.User do end end - def is_confirmed(%User{confirmed_at: nil} = _user) do - {:error, :unconfirmed} - end - - def is_confirmed(%User{} = user) do - {:ok, user} - end + def is_confirmed(%User{confirmed_at: nil} = _user), do: {:error, :unconfirmed} + def is_confirmed(%User{} = user), do: {:ok, user} def owns_actor(%User{actors: actors}, actor_id) do case Enum.find(actors, fn a -> a.id == actor_id end) do diff --git a/lib/mobilizon_web/resolvers/config.ex b/lib/mobilizon_web/resolvers/config.ex new file mode 100644 index 000000000..931403c99 --- /dev/null +++ b/lib/mobilizon_web/resolvers/config.ex @@ -0,0 +1,14 @@ +defmodule MobilizonWeb.Resolvers.Config do + @moduledoc """ + Handles the config-related GraphQL calls + """ + require Logger + import Mobilizon.CommonConfig + + @doc """ + Get config + """ + def get_config(_parent, _params, _context) do + {:ok, %{name: instance_name(), registrations_open: registrations_open?()}} + end +end diff --git a/lib/mobilizon_web/resolvers/user.ex b/lib/mobilizon_web/resolvers/user.ex index 974568196..fed884d19 100644 --- a/lib/mobilizon_web/resolvers/user.ex +++ b/lib/mobilizon_web/resolvers/user.ex @@ -3,6 +3,7 @@ defmodule MobilizonWeb.Resolvers.User do Handles the user-related GraphQL calls """ alias Mobilizon.Actors.Actor + alias Mobilizon.CommonConfig alias Mobilizon.Users.User alias Mobilizon.{Actors, Users} alias Mobilizon.Service.Users.{ResetPassword, Activation} @@ -64,15 +65,23 @@ defmodule MobilizonWeb.Resolvers.User do end @doc """ - Register an user : + Register an user: + - check registrations are enabled - create the user - send a validation email to the user """ @spec create_user(any(), map(), any()) :: tuple() def create_user(_parent, args, _resolution) do - with {:ok, %User{} = user} <- Users.register(args) do + with {:registrations_open, true} <- {:registrations_open, CommonConfig.registrations_open?()}, + {:ok, %User{} = user} <- Users.register(args) do Activation.send_confirmation_email(user) {:ok, user} + else + {:registrations_open, false} -> + {:error, "Registrations are not enabled"} + + err -> + err end end diff --git a/lib/mobilizon_web/schema.ex b/lib/mobilizon_web/schema.ex index 0373b80ce..4a8f868cf 100644 --- a/lib/mobilizon_web/schema.ex +++ b/lib/mobilizon_web/schema.ex @@ -18,6 +18,7 @@ defmodule MobilizonWeb.Schema do import_types(MobilizonWeb.Schema.Actors.PersonType) import_types(MobilizonWeb.Schema.Actors.GroupType) import_types(MobilizonWeb.Schema.CommentType) + import_types(MobilizonWeb.Schema.ConfigType) alias MobilizonWeb.Resolvers @@ -133,6 +134,7 @@ defmodule MobilizonWeb.Schema do import_fields(:participant_queries) import_fields(:tag_queries) import_fields(:address_queries) + import_fields(:config_queries) end @desc """ diff --git a/lib/mobilizon_web/schema/config.ex b/lib/mobilizon_web/schema/config.ex new file mode 100644 index 000000000..ea7e9259e --- /dev/null +++ b/lib/mobilizon_web/schema/config.ex @@ -0,0 +1,23 @@ +defmodule MobilizonWeb.Schema.ConfigType do + @moduledoc """ + Schema representation for User + """ + use Absinthe.Schema.Notation + + alias MobilizonWeb.Resolvers.Config + + @desc "A config object" + object :config do + # Instance name + field(:name, :string) + + field(:registrations_open, :boolean) + end + + object :config_queries do + @desc "Get the instance config" + field :config, :config do + resolve(&Config.get_config/3) + end + end +end diff --git a/test/mobilizon_web/resolvers/config_resolver_test.exs b/test/mobilizon_web/resolvers/config_resolver_test.exs new file mode 100644 index 000000000..bdbbc0b91 --- /dev/null +++ b/test/mobilizon_web/resolvers/config_resolver_test.exs @@ -0,0 +1,25 @@ +defmodule MobilizonWeb.Resolvers.ConfigResolverTest do + alias MobilizonWeb.AbsintheHelpers + use MobilizonWeb.ConnCase + use Bamboo.Test + + describe "Resolver: Get config" do + test "get_config/3 returns the instance config", context do + query = """ + { + config { + name, + registrationsOpen + } + } + """ + + res = + context.conn + |> get("/api", AbsintheHelpers.query_skeleton(query, "config")) + + assert json_response(res, 200)["data"]["config"]["name"] == "Localhost" + assert json_response(res, 200)["data"]["config"]["registrationsOpen"] == true + end + end +end diff --git a/test/mobilizon_web/resolvers/user_resolver_test.exs b/test/mobilizon_web/resolvers/user_resolver_test.exs index ffd47e4cd..5db02f088 100644 --- a/test/mobilizon_web/resolvers/user_resolver_test.exs +++ b/test/mobilizon_web/resolvers/user_resolver_test.exs @@ -1,11 +1,12 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do use MobilizonWeb.ConnCase - alias Mobilizon.{Actors, Users} + alias Mobilizon.{Actors, Users, CommonConfig} alias Mobilizon.Actors.Actor alias Mobilizon.Users.User alias MobilizonWeb.AbsintheHelpers alias Mobilizon.Service.Users.ResetPassword import Mobilizon.Factory + import Mock use Bamboo.Test @valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"} @@ -389,6 +390,29 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do assert hd(json_response(res, 200)["errors"])["message"] == "Email doesn't fit required format" end + + test "test create_user/3 doesn't create a user when registration is disabled", context do + with_mock CommonConfig, registrations_open?: fn -> false end do + mutation = """ + mutation { + createUser( + email: "#{@user_creation.email}", + password: "#{@user_creation.password}", + ) { + id, + email + } + } + """ + + res = + context.conn + |> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) + + assert hd(json_response(res, 200)["errors"])["message"] == + "Registrations are not enabled" + end + end end describe "Resolver: Validate an user" do