Skip to content

Commit

Permalink
Update registration via invitation
Browse files Browse the repository at this point in the history
Here, we still rely on "polymorphic" invitation structures,
hence the "unified by id" helper.

For now, it'll remain local unless we discover it's
needed in the broader `Teams.Invitations` context.

cc @zoldar
  • Loading branch information
aerosol committed Dec 10, 2024
1 parent a2fb761 commit 148ae9c
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 29 deletions.
51 changes: 50 additions & 1 deletion lib/plausible_web/live/register_form.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ defmodule PlausibleWeb.Live.RegisterForm do

alias Plausible.Auth
alias Plausible.Repo
alias Plausible.Teams

def mount(params, _session, socket) do
socket =
assign_new(socket, :invitation, fn ->
if invitation_id = params["invitation_id"] do
Repo.get_by(Auth.Invitation, invitation_id: invitation_id)
case find_by_id_unified(invitation_id) do
{:error, :invitation_not_found} -> nil
{:ok, unified} -> unified
end
end
end)

Expand Down Expand Up @@ -340,4 +344,49 @@ defmodule PlausibleWeb.Live.RegisterForm do
)}
end
end

defp find_by_id_unified(invitation_or_transfer_id) do
with {:error, :invitation_not_found} <-
find_invitation_by_id_unified(invitation_or_transfer_id) do
find_transfer_by_id_unified(invitation_or_transfer_id)
end
end

defp find_invitation_by_id_unified(id) do
invitation =
Teams.GuestInvitation
|> Repo.get_by(invitation_id: id)
|> Repo.preload([:site, team_invitation: :inviter])

case invitation do
nil ->
{:error, :invitation_not_found}

guest_invitation ->
{:ok,
%{
role: guest_invitation.role,
email: guest_invitation.team_invitation.email
}}
end
end

defp find_transfer_by_id_unified(id) do
transfer =
Teams.SiteTransfer
|> Repo.get_by(transfer_id: id)
|> Repo.preload([:site, :initiator])

case transfer do
nil ->
{:error, :invitation_not_found}

transfer ->
{:ok,
%{
role: :owner,
email: transfer.email
}}
end
end
end
45 changes: 17 additions & 28 deletions test/plausible_web/live/register_form_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ defmodule PlausibleWeb.Live.RegisterFormTest do
import Phoenix.LiveViewTest
import Plausible.Test.Support.HTML

use Plausible.Teams.Test

alias Plausible.Auth.User
alias Plausible.Repo

Expand Down Expand Up @@ -138,16 +140,11 @@ defmodule PlausibleWeb.Live.RegisterFormTest do

describe "/register/invitation/:invitation_id" do
setup do
inviter = insert(:user)
site = insert(:site, members: [inviter])
inviter = new_user()
site = new_site(owner: inviter)

invitation =
insert(:invitation,
site_id: site.id,
inviter: inviter,
email: "[email protected]",
role: :admin
)
invite_guest(site, "[email protected]", role: :editor, inviter: inviter)

{:ok, %{site: site, invitation: invitation, inviter: inviter}}
end
Expand Down Expand Up @@ -183,13 +180,14 @@ defmodule PlausibleWeb.Live.RegisterFormTest do
assert text_of_attr(password_input, "value") == "very-long-and-very-secret-123"
assert text_of_attr(password_confirmation_input, "value") == "very-long-and-very-secret-123"

assert %{
name: "Mary Sue",
email: "[email protected]",
password_hash: password_hash,
# leaves trial_expiry_date null when invitation role is not :owner
trial_expiry_date: nil
} = Repo.get_by(User, email: "[email protected]")
assert user =
%{
name: "Mary Sue",
email: "[email protected]",
password_hash: password_hash
} = Repo.get_by(User, email: "[email protected]")

assert team_of(user) == nil

assert String.length(password_hash) > 0
end
Expand All @@ -201,28 +199,19 @@ defmodule PlausibleWeb.Live.RegisterFormTest do
} do
mock_captcha_success()

invitation =
insert(:invitation,
site_id: site.id,
inviter: inviter,
email: "[email protected]",
role: :owner
)
invitation = invite_transfer(site, "[email protected]", inviter: inviter)

lv = get_liveview(conn, "/register/invitation/#{invitation.invitation_id}")
lv = get_liveview(conn, "/register/invitation/#{invitation.transfer_id}")

type_into_input(lv, "user[name]", "Mary Sue")
type_into_input(lv, "user[password]", "very-long-and-very-secret-123")
type_into_input(lv, "user[password_confirmation]", "very-long-and-very-secret-123")

_html = lv |> element("form") |> render_submit()

assert %{
email: "[email protected]",
trial_expiry_date: trial_expiry_date
} = Repo.get_by(User, email: "[email protected]")
assert user = Repo.get_by(User, email: "[email protected]")

assert trial_expiry_date != nil
assert team_of(user).trial_expiry_date != nil
end

test "always uses original email from the invitation", %{conn: conn, invitation: invitation} do
Expand Down

0 comments on commit 148ae9c

Please sign in to comment.