action_fallback(:errors)
def confirm_email(conn, %{"user_id" => uid, "token" => token}) do
- with %User{} = user <- User.get_cached_by_id(uid),
- true <- user.local and !user.is_confirmed and user.confirmation_token == token,
- {:ok, _} <- User.confirm(user) do
- redirect(conn, to: "/")
+ case User.get_cached_by_id(uid) do
+ %User{local: true, is_confirmed: false, confirmation_token: ^token} = user ->
+ case User.confirm(user) do
+ {:ok, _} ->
+ redirect(conn, to: "/")
+
+ {:error, _} ->
+ json_reply(conn, 400, "Unable to confirm")
+ end
+
+ %User{is_confirmed: true} ->
+ json_reply(conn, 400, "Already verified email")
+
+ _ ->
+ json_reply(conn, 400, "Couldn't verify email")
end
end
refute user.confirmation_token
end
- test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
+ test "confirmation is requested twice", %{conn: conn, user: user} do
+ conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.confirmation_token}")
+ assert 302 == conn.status
+
+ conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.confirmation_token}")
+ assert 400 == conn.status
+ assert "Already verified email" == conn.resp_body
+
+ user = User.get_cached_by_id(user.id)
+
+ assert user.is_confirmed
+ refute user.confirmation_token
+ end
+
+ test "it returns 400 if user cannot be found by id", %{conn: conn, user: user} do
conn = get(conn, "/api/account/confirm_email/0/#{user.confirmation_token}")
- assert 500 == conn.status
+ assert 400 == conn.status
end
- test "it returns 500 if token is invalid", %{conn: conn, user: user} do
+ test "it returns 400 if token is invalid", %{conn: conn, user: user} do
conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
- assert 500 == conn.status
+ assert 400 == conn.status
end
end