Skip to content

Commit

Permalink
improve transfer ownership error message (#2651)
Browse files Browse the repository at this point in the history
* improve transfer ownership error message

* add changelog

* simplify

* revert changeset invitation error message

* more descriptive error message

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
  • Loading branch information
ruslandoga and aerosol committed Feb 13, 2023
1 parent 35e7a3d commit e9ba60c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
- Fix breakdown API pagination when using event metrics plausible/analytics#2562
- Automatically update all visible dashboard reports in the realtime view
- Connect via TLS when using HTTPS scheme in ClickHouse URL plausible/analytics#2570
- Add error message in case a transfer to an invited (but not joined) user is requested plausible/analytics#2651
- Fix bug with [showing property breakdown with a prop filter](https://github.com/plausible/analytics/issues/1789)
- Fix bug when combining goal and prop filters plausible/analytics#2654

Expand Down
13 changes: 13 additions & 0 deletions lib/plausible/helpers/changeset.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule Plausible.ChangesetHelpers do
@moduledoc "Helper function for working with Ecto changesets"

def traverse_errors(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} ->
Regex.replace(~r"%{(\w+)}", msg, fn _, key ->
opts
|> Keyword.get(String.to_existing_atom(key), key)
|> to_string()
end)
end)
end
end
14 changes: 2 additions & 12 deletions lib/plausible_web/controllers/api/external_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ defmodule PlausibleWeb.Api.ExternalController do
conn
|> put_resp_header("x-plausible-dropped", "#{Enum.count(dropped)}")
|> put_status(400)
|> json(%{errors: traverse_errors(first_invalid_changeset)})
|> json(%{errors: Plausible.ChangesetHelpers.traverse_errors(first_invalid_changeset)})
else
conn
|> put_resp_header("x-plausible-dropped", "#{Enum.count(dropped)}")
Expand All @@ -38,7 +38,7 @@ defmodule PlausibleWeb.Api.ExternalController do
{:error, %Ecto.Changeset{} = changeset} ->
conn
|> put_status(400)
|> json(%{errors: traverse_errors(changeset)})
|> json(%{errors: Plausible.ChangesetHelpers.traverse_errors(changeset)})
end
end

Expand Down Expand Up @@ -102,14 +102,4 @@ defmodule PlausibleWeb.Api.ExternalController do
end
end)
end

defp traverse_errors(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} ->
Regex.replace(~r"%{(\w+)}", msg, fn _, key ->
opts
|> Keyword.get(String.to_existing_atom(key), key)
|> to_string()
end)
end)
end
end
35 changes: 27 additions & 8 deletions lib/plausible_web/controllers/site/membership_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,41 @@ defmodule PlausibleWeb.Site.MembershipController do
site = Sites.get_for_user!(conn.assigns[:current_user].id, site_domain)
user = Plausible.Auth.find_user_by(email: email)

invitation =
invite_result =
Invitation.new(%{
email: email,
role: :owner,
site_id: site.id,
inviter_id: conn.assigns[:current_user].id
})
|> Repo.insert!()
|> Repo.preload([:site, :inviter])
|> Repo.insert()

PlausibleWeb.Email.ownership_transfer_request(invitation, user)
|> Plausible.Mailer.send()
conn =
case invite_result do
{:ok, invitation} ->
invitation
|> Repo.preload([:site, :inviter])
|> PlausibleWeb.Email.ownership_transfer_request(user)
|> Plausible.Mailer.send()

put_flash(conn, :success, "Site transfer request has been sent to #{email}")

{:error, changeset} ->
errors = Plausible.ChangesetHelpers.traverse_errors(changeset)

message =
case errors do
%{invitation: ["already sent" | _]} -> "Invitation has already been sent"
_other -> "Site transfer request to #{email} has failed"
end

conn
|> put_flash(:ttl, :timer.seconds(5))
|> put_flash(:error_title, "Transfer error")
|> put_flash(:error, message)
end

conn
|> put_flash(:success, "Site transfer request has been sent to #{email}")
|> redirect(to: Routes.site_path(conn, :settings_people, site.domain))
redirect(conn, to: Routes.site_path(conn, :settings_people, site.domain))
end

@doc """
Expand Down
27 changes: 27 additions & 0 deletions test/plausible_web/controllers/site/membership_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,33 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do

refute Repo.get_by(Plausible.Auth.Invitation, email: "john.doe@example.com")
end

test "fails to transfer ownership to invited user with proper error message", ctx do
%{conn: conn, user: user} = ctx
site = insert(:site, members: [user])
invited = "john.doe@example.com"

# invite a user but don't join

conn =
post(conn, "/sites/#{site.domain}/memberships/invite", %{
email: invited,
role: "admin"
})

conn = get(recycle(conn), redirected_to(conn, 302))

assert html_response(conn, 200) =~
"#{invited} has been invited to #{site.domain} as an admin"

# transferring ownership to that domain now fails

conn = post(conn, "/sites/#{site.domain}/transfer-ownership", %{email: invited})
conn = get(recycle(conn), redirected_to(conn, 302))
html = html_response(conn, 200)
assert html =~ "Transfer error"
assert html =~ "Invitation has already been sent"
end
end

describe "PUT /sites/memberships/:id/role/:new_role" do
Expand Down

0 comments on commit e9ba60c

Please sign in to comment.