Packages
phoenix_kit
1.7.4
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit_web/users/magic_link_registration.ex
defmodule PhoenixKitWeb.Users.MagicLinkRegistration do
@moduledoc """
LiveView for magic link registration completion form.
"""
use PhoenixKitWeb, :live_view
alias PhoenixKit.ReferralCodes
alias PhoenixKit.Users.Auth
alias PhoenixKit.Users.Auth.User
alias PhoenixKit.Users.MagicLinkRegistration
alias PhoenixKit.Utils.Routes
@impl true
def mount(%{"token" => token}, _session, socket) do
case MagicLinkRegistration.verify_registration_token(token) do
{:ok, email} ->
# Get referral codes configuration
referral_codes_config = ReferralCodes.get_config()
# Generate username suggestion from email
suggested_username = User.generate_username_from_email(email)
changeset =
Auth.change_user_registration(%User{
email: email,
username: suggested_username
})
# Extract IP address for geolocation
ip_address =
case get_connect_info(socket, :peer_data) do
%{address: {a, b, c, d}} -> "#{a}.#{b}.#{c}.#{d}"
%{address: address} -> to_string(address)
_ -> "unknown"
end
{:ok,
socket
|> assign(:page_title, "Complete Registration")
|> assign(:token, token)
|> assign(:email, email)
|> assign(:ip_address, ip_address)
|> assign(:referral_codes_enabled, referral_codes_config.enabled)
|> assign(:referral_codes_required, referral_codes_config.required)
|> assign(:referral_code, nil)
|> assign(:referral_code_error, nil)
|> assign(:trigger_submit, false)
|> assign(:check_errors, false)
|> assign_form(changeset)}
{:error, _} ->
{:ok,
socket
|> put_flash(:error, "Registration link is invalid or has expired.")
|> redirect(to: Routes.path("/users/register"))}
end
end
@impl true
def handle_event("validate", %{"user" => user_params} = params, socket) do
referral_code = params["referral_code"]
case validate_referral_code(referral_code, socket) do
{:ok, _} ->
socket =
socket
|> assign(referral_code: referral_code)
|> assign(referral_code_error: nil)
changeset =
%User{email: socket.assigns.email}
|> Auth.change_user_registration(user_params)
|> Map.put(:action, :validate)
{:noreply, assign_form(socket, changeset)}
{:error, error_message} ->
socket =
socket
|> assign(referral_code: referral_code)
|> assign(referral_code_error: error_message)
changeset =
%User{email: socket.assigns.email}
|> Auth.change_user_registration(user_params)
|> Map.put(:action, :validate)
{:noreply, assign_form(socket, changeset)}
end
end
@impl true
def handle_event("save", %{"user" => user_params} = params, socket) do
referral_code = params["referral_code"]
case validate_referral_code(referral_code, socket) do
{:ok, _validated_code} ->
# Add referral_code to user params
user_params =
if referral_code && String.trim(referral_code) != "" do
Map.put(user_params, "referral_code", referral_code)
else
user_params
end
# Complete registration
case MagicLinkRegistration.complete_registration(
socket.assigns.token,
user_params,
socket.assigns.ip_address
) do
{:ok, user} ->
changeset = Auth.change_user_registration(user)
{:noreply, socket |> assign(trigger_submit: true) |> assign_form(changeset)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, socket |> assign(check_errors: true) |> assign_form(changeset)}
end
{:error, error_message} ->
socket =
socket
|> assign(referral_code: referral_code)
|> assign(referral_code_error: error_message)
|> assign(check_errors: true)
{:noreply, socket}
end
end
defp assign_form(socket, %Ecto.Changeset{} = changeset) do
form = to_form(changeset, as: "user")
if changeset.valid? do
assign(socket, form: form, check_errors: false)
else
assign(socket, form: form)
end
end
defp validate_referral_code(referral_code, socket) do
cond do
not socket.assigns.referral_codes_enabled ->
{:ok, nil}
socket.assigns.referral_codes_required and
(is_nil(referral_code) or String.trim(referral_code) == "") ->
{:error, "Referral code is required"}
referral_code && String.trim(referral_code) != "" ->
validate_referral_code_value(String.trim(referral_code))
true ->
{:ok, nil}
end
end
defp validate_referral_code_value(code_string) do
case ReferralCodes.get_code_by_string(code_string) do
nil ->
{:error, "Invalid referral code"}
code ->
cond do
not code.status ->
{:error, "This referral code is no longer active"}
ReferralCodes.expired?(code) ->
{:error, "This referral code has expired"}
ReferralCodes.usage_limit_reached?(code) ->
{:error, "This referral code has reached its usage limit"}
true ->
{:ok, code}
end
end
end
end