diff --git a/lib/cannery/accounts.ex b/lib/cannery/accounts.ex index b1294fb..d453473 100644 --- a/lib/cannery/accounts.ex +++ b/lib/cannery/accounts.ex @@ -21,6 +21,7 @@ defmodule Cannery.Accounts do nil """ + @spec get_user_by_email(String.t()) :: User.t() | nil def get_user_by_email(email) when is_binary(email) do Repo.get_by(User, email: email) end @@ -37,6 +38,8 @@ defmodule Cannery.Accounts do nil """ + @spec get_user_by_email_and_password(String.t(), String.t()) :: + User.t() | nil def get_user_by_email_and_password(email, password) when is_binary(email) and is_binary(password) do user = Repo.get_by(User, email: email) @@ -57,6 +60,7 @@ defmodule Cannery.Accounts do ** (Ecto.NoResultsError) """ + @spec get_user!(Ecto.UUID.t()) :: User.t() def get_user!(id), do: Repo.get!(User, id) @spec list_users_by_role(atom()) :: [User.t()] @@ -88,6 +92,7 @@ defmodule Cannery.Accounts do {:error, %Ecto.Changeset{}} """ + @spec register_user(map()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()} def register_user(attrs) do # if no registered users, make first user an admin attrs = @@ -107,7 +112,8 @@ defmodule Cannery.Accounts do %Ecto.Changeset{data: %User{}} """ - def change_user_registration(%User{} = user, attrs \\ %{}) do + @spec change_user_registration(User.t(), map()) :: Ecto.Changeset.t() + def change_user_registration(user, attrs \\ %{}) do User.registration_changeset(user, attrs, hash_password: false) end @@ -122,6 +128,7 @@ defmodule Cannery.Accounts do %Ecto.Changeset{data: %User{}} """ + @spec change_user_email(User.t(), map()) :: Ecto.Changeset.t() def change_user_email(user, attrs \\ %{}) do User.email_changeset(user, attrs) end @@ -153,6 +160,8 @@ defmodule Cannery.Accounts do {:error, %Ecto.Changeset{}} """ + @spec apply_user_email(User.t(), String.t(), map()) :: + {:ok, User.t()} | {:error, Ecto.Changeset.t()} def apply_user_email(user, password, attrs) do user |> User.email_changeset(attrs) @@ -166,6 +175,7 @@ defmodule Cannery.Accounts do If the token matches, the user email is updated and the token is deleted. The confirmed_at date is also updated to the current time. """ + @spec update_user_email(User.t(), UserToken.t()) :: {:ok, any()} | :error def update_user_email(user, token) do context = "change:#{user.email}" @@ -195,7 +205,9 @@ defmodule Cannery.Accounts do {:ok, %{to: ..., body: ...}} """ - def deliver_update_email_instructions(%User{} = user, current_email, update_email_url_fun) + @spec deliver_update_email_instructions(User.t(), String.t(), function) :: + {:ok, any()} | {:error, atom()} + def deliver_update_email_instructions(user, current_email, update_email_url_fun) when is_function(update_email_url_fun, 1) do {encoded_token, user_token} = UserToken.build_email_token(user, "change:#{current_email}") @@ -212,6 +224,7 @@ defmodule Cannery.Accounts do %Ecto.Changeset{data: %User{}} """ + @spec change_user_password(User.t(), map()) :: Ecto.Changeset.t() def change_user_password(user, attrs \\ %{}) do User.password_changeset(user, attrs, hash_password: false) end @@ -228,6 +241,8 @@ defmodule Cannery.Accounts do {:error, %Ecto.Changeset{}} """ + @spec update_user_password(User.t(), String.t(), map()) :: + {:ok, User.t()} | {:error, Ecto.Changeset.t()} def update_user_password(user, password, attrs) do changeset = user @@ -245,7 +260,7 @@ defmodule Cannery.Accounts do end @spec delete_user!(User.t()) :: User.t() - def delete_user!(%User{} = user) do + def delete_user!(user) do user |> Repo.delete!() end @@ -254,6 +269,7 @@ defmodule Cannery.Accounts do @doc """ Generates a session token. """ + @spec generate_user_session_token(User.t()) :: UserToken.t() def generate_user_session_token(user) do {token, user_token} = UserToken.build_session_token(user) Repo.insert!(user_token) @@ -263,6 +279,7 @@ defmodule Cannery.Accounts do @doc """ Gets the user with the given signed token. """ + @spec get_user_by_session_token(UserToken.t()) :: User.t() def get_user_by_session_token(token) do {:ok, query} = UserToken.verify_session_token_query(token) Repo.one(query) @@ -271,6 +288,7 @@ defmodule Cannery.Accounts do @doc """ Deletes the signed token with the given context. """ + @spec delete_session_token(UserToken.t()) :: :ok def delete_session_token(token) do Repo.delete_all(UserToken.token_and_context_query(token, "session")) :ok @@ -279,6 +297,7 @@ defmodule Cannery.Accounts do @doc """ Returns a boolean if registration is allowed or not """ + @spec allow_registration?() :: boolean() def allow_registration?() do Application.get_env(:cannery, CanneryWeb.Endpoint)[:registration] == "public" or list_users_by_role(:admin) |> Enum.empty?() @@ -298,7 +317,9 @@ defmodule Cannery.Accounts do {:error, :already_confirmed} """ - def deliver_user_confirmation_instructions(%User{} = user, confirmation_url_fun) + @spec deliver_user_confirmation_instructions(User.t(), function) :: + {:ok, any()} | {:error, atom()} + def deliver_user_confirmation_instructions(user, confirmation_url_fun) when is_function(confirmation_url_fun, 1) do if user.confirmed_at do {:error, :already_confirmed} @@ -315,6 +336,7 @@ defmodule Cannery.Accounts do If the token matches, the user account is marked as confirmed and the token is deleted. """ + @spec confirm_user(UserToken.t()) :: {:ok, User.t()} | atom() def confirm_user(token) do with {:ok, query} <- UserToken.verify_email_token_query(token, "confirm"), %User{} = user <- Repo.one(query), @@ -342,7 +364,9 @@ defmodule Cannery.Accounts do {:ok, %{to: ..., body: ...}} """ - def deliver_user_reset_password_instructions(%User{} = user, reset_password_url_fun) + @spec deliver_user_reset_password_instructions(User.t(), function()) :: + {:ok, any()} | {:error, atom()} + def deliver_user_reset_password_instructions(user, reset_password_url_fun) when is_function(reset_password_url_fun, 1) do {encoded_token, user_token} = UserToken.build_email_token(user, "reset_password") Repo.insert!(user_token) @@ -361,6 +385,7 @@ defmodule Cannery.Accounts do nil """ + @spec get_user_by_reset_password_token(UserToken.t()) :: User.t() | nil def get_user_by_reset_password_token(token) do with {:ok, query} <- UserToken.verify_email_token_query(token, "reset_password"), %User{} = user <- Repo.one(query) do @@ -382,6 +407,7 @@ defmodule Cannery.Accounts do {:error, %Ecto.Changeset{}} """ + @spec reset_user_password(User.t(), map()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()} def reset_user_password(user, attrs) do Ecto.Multi.new() |> Ecto.Multi.update(:user, User.password_changeset(user, attrs)) diff --git a/lib/cannery/invites.ex b/lib/cannery/invites.ex index 0b45916..92fe810 100644 --- a/lib/cannery/invites.ex +++ b/lib/cannery/invites.ex @@ -18,6 +18,7 @@ defmodule Cannery.Invites do [%Invite{}, ...] """ + @spec list_invites() :: [Invite.t()] def list_invites, do: Repo.all(Invite) @doc """ @@ -34,6 +35,7 @@ defmodule Cannery.Invites do ** (Ecto.NoResultsError) """ + @spec get_invite!(Ecto.UUID.t()) :: Invite.t() def get_invite!(id), do: Repo.get!(Invite, id) @doc """ @@ -95,7 +97,7 @@ defmodule Cannery.Invites do """ @spec create_invite(Accounts.User.t() | Ecto.UUID.t(), map()) :: Invite.t() - def create_invite(%Accounts.User{id: user_id}, attrs) do + def create_invite(%{id: user_id}, attrs) do create_invite(user_id, attrs) end @@ -125,10 +127,9 @@ defmodule Cannery.Invites do {:error, %Ecto.Changeset{}} """ - def update_invite(%Invite{} = invite, attrs) do - invite - |> Invite.changeset(attrs) - |> Repo.update() + @spec update_invite(Invite.t(), map()) :: {:ok, Invite.t()} | {:error, Ecto.Changeset.t()} + def update_invite(invite, attrs) do + invite |> Invite.changeset(attrs) |> Repo.update() end @doc """ @@ -143,7 +144,8 @@ defmodule Cannery.Invites do {:error, %Ecto.Changeset{}} """ - def delete_invite(%Invite{} = invite) do + @spec delete_invite(Invite.t()) :: {:ok, Invite.t()} | {:error, Ecto.Changeset.t()} + def delete_invite(invite) do Repo.delete(invite) end @@ -156,7 +158,9 @@ defmodule Cannery.Invites do %Ecto.Changeset{data: %Invite{}} """ - def change_invite(%Invite{} = invite, attrs \\ %{}) do + @spec change_invite(Invite.t()) :: Ecto.Changeset.t() + @spec change_invite(Invite.t(), map()) :: Ecto.Changeset.t() + def change_invite(invite, attrs \\ %{}) do Invite.changeset(invite, attrs) end end