diff --git a/elixir/README.md b/elixir/README.md index 07f230c9f..185b81021 100644 --- a/elixir/README.md +++ b/elixir/README.md @@ -404,13 +404,13 @@ Interactive Elixir (1.15.2) - press Ctrl+C to exit (type h() ENTER for help) iex(web@web-3vmw.us-east1-d.c.firezone-staging.internal)1> {:ok, account} = Domain.Accounts.create_account(%{name: "Firezone", slug: "firezone"}) {:ok, ...} -iex(web@web-3vmw.us-east1-d.c.firezone-staging.internal)2> {:ok, magic_link_provider} = Domain.Auth.create_provider(account, %{name: "Email", adapter: :email, adapter_config: %{}}) +iex(web@web-3vmw.us-east1-d.c.firezone-staging.internal)2> {:ok, email_provider} = Domain.Auth.create_provider(account, %{name: "Email (OTP)", adapter: :email, adapter_config: %{}}) {:ok, ...} iex(web@web-3vmw.us-east1-d.c.firezone-staging.internal)3> {:ok, actor} = Domain.Actors.create_actor(account, %{type: :account_admin_user, name: "Andrii Dryga"}) {:ok, ...} -iex(web@web-3vmw.us-east1-d.c.firezone-staging.internal)4> {:ok, identity} = Domain.Auth.upsert_identity(actor, magic_link_provider, %{provider_identifier: "a@firezone.dev", provider_identifier_confirmation: "a@firezone.dev"}) +iex(web@web-3vmw.us-east1-d.c.firezone-staging.internal)4> {:ok, identity} = Domain.Auth.upsert_identity(actor, email_provider, %{provider_identifier: "a@firezone.dev", provider_identifier_confirmation: "a@firezone.dev"}) ... iex(web@web-3vmw.us-east1-d.c.firezone-staging.internal)5> context = %Domain.Auth.Context{type: :browser, user_agent: "User-Agent: iOS/12.7 (iPhone) connlib/0.7.412", remote_ip: {127, 0, 0, 1}} diff --git a/elixir/apps/domain/lib/domain/auth.ex b/elixir/apps/domain/lib/domain/auth.ex index 9433a7193..431495a44 100644 --- a/elixir/apps/domain/lib/domain/auth.ex +++ b/elixir/apps/domain/lib/domain/auth.ex @@ -72,7 +72,7 @@ defmodule Domain.Auth do alias Domain.Auth.Identity # This session duration is used when IdP doesn't return the token expiration date, - # or no IdP is used (eg. sign in via magic link or userpass). + # or no IdP is used (eg. sign in via email or userpass). @default_session_duration_hours [ browser: [ account_admin_user: 10, @@ -310,7 +310,7 @@ defmodule Domain.Auth do end) end - # used during magic link auth flow + # used during email auth flow def fetch_active_identity_by_provider_and_identifier( %Provider{adapter: :email} = provider, provider_identifier, diff --git a/elixir/apps/domain/lib/domain/billing/event_handler.ex b/elixir/apps/domain/lib/domain/billing/event_handler.ex index 67396932f..dd89126b8 100644 --- a/elixir/apps/domain/lib/domain/billing/event_handler.ex +++ b/elixir/apps/domain/lib/domain/billing/event_handler.ex @@ -267,9 +267,9 @@ defmodule Domain.Billing.EventHandler do membership_rules: [%{operator: true}] }) - {:ok, magic_link_provider} = + {:ok, email_provider} = Domain.Auth.create_provider(account, %{ - name: "Email", + name: "Email (OTP)", adapter: :email, adapter_config: %{} }) @@ -281,7 +281,7 @@ defmodule Domain.Billing.EventHandler do }) {:ok, _identity} = - Domain.Auth.upsert_identity(actor, magic_link_provider, %{ + Domain.Auth.upsert_identity(actor, email_provider, %{ provider_identifier: metadata["account_admin_email"] || account_email, provider_identifier_confirmation: metadata["account_admin_email"] || account_email }) diff --git a/elixir/apps/domain/lib/domain/ops.ex b/elixir/apps/domain/lib/domain/ops.ex index b94cfae1e..c48757021 100644 --- a/elixir/apps/domain/lib/domain/ops.ex +++ b/elixir/apps/domain/lib/domain/ops.ex @@ -27,7 +27,7 @@ defmodule Domain.Ops do membership_rules: [%{operator: true}] }) - {:ok, magic_link_provider} = + {:ok, email_provider} = Domain.Auth.create_provider(account, %{ name: "Email", adapter: :email, @@ -41,12 +41,12 @@ defmodule Domain.Ops do }) {:ok, identity} = - Domain.Auth.upsert_identity(actor, magic_link_provider, %{ + Domain.Auth.upsert_identity(actor, email_provider, %{ provider_identifier: account_admin_email, provider_identifier_confirmation: account_admin_email }) - %{account: account, provider: magic_link_provider, actor: actor, identity: identity} + %{account: account, provider: email_provider, actor: actor, identity: identity} end) end @@ -76,13 +76,13 @@ defmodule Domain.Ops do Domain.Repo.transaction(fn -> {:ok, account} = Domain.Accounts.fetch_account_by_id_or_slug(account_slug) providers = Domain.Auth.all_active_providers_for_account!(account) - magic_link_provider = Enum.find(providers, fn provider -> provider.adapter == :email end) + email_provider = Enum.find(providers, fn provider -> provider.adapter == :email end) {:ok, actor} = Domain.Actors.create_actor(account, %{type: :account_admin_user, name: "Firezone Support"}) {:ok, identity} = - Domain.Auth.upsert_identity(actor, magic_link_provider, %{ + Domain.Auth.upsert_identity(actor, email_provider, %{ provider_identifier: "ent-support@firezone.dev", provider_identifier_confirmation: "ent-support@firezone.dev" }) diff --git a/elixir/apps/domain/priv/repo/migrations/20240721181834_rename_magic_link_to_email_otp.exs b/elixir/apps/domain/priv/repo/migrations/20240721181834_rename_magic_link_to_email_otp.exs new file mode 100644 index 000000000..eb28e18d3 --- /dev/null +++ b/elixir/apps/domain/priv/repo/migrations/20240721181834_rename_magic_link_to_email_otp.exs @@ -0,0 +1,12 @@ +defmodule Domain.Repo.Migrations.RenameMagicLinkToEmailOTP do + use Ecto.Migration + + def change do + """ + UPDATE auth_providers + SET name = 'Email (OTP)' + WHERE adapter = 'email'; + """ + |> execute("") + end +end diff --git a/elixir/apps/web/lib/web/controllers/auth_controller.ex b/elixir/apps/web/lib/web/controllers/auth_controller.ex index 8035d56c1..c351846fb 100644 --- a/elixir/apps/web/lib/web/controllers/auth_controller.ex +++ b/elixir/apps/web/lib/web/controllers/auth_controller.ex @@ -62,7 +62,7 @@ defmodule Web.AuthController do @doc """ This is a callback for the Email provider which sends login link. """ - def request_magic_link( + def request_email_otp( conn, %{ "account_id_or_slug" => account_id_or_slug, @@ -76,7 +76,7 @@ defmodule Web.AuthController do with true <- String.contains?(provider_identifier, "@"), {:ok, provider} <- Domain.Auth.fetch_active_provider_by_id(provider_id) do - conn = maybe_send_magic_link_email(conn, provider, provider_identifier, redirect_params) + conn = maybe_send_email_otp(conn, provider, provider_identifier, redirect_params) signed_provider_identifier = Plug.Crypto.sign( @@ -110,7 +110,7 @@ defmodule Web.AuthController do end end - defp maybe_send_magic_link_email(conn, provider, provider_identifier, redirect_params) do + defp maybe_send_email_otp(conn, provider, provider_identifier, redirect_params) do context_type = Web.Auth.fetch_auth_context_type!(redirect_params) context = Web.Auth.get_auth_context(conn, context_type) @@ -125,7 +125,7 @@ defmodule Web.AuthController do ), {:ok, identity} <- Domain.Auth.Adapters.Email.request_sign_in_token(identity, context), - {:ok, fragment} <- send_magic_link_email(conn, identity, redirect_params) do + {:ok, fragment} <- send_email_otp(conn, identity, redirect_params) do fragment else _ -> @@ -144,7 +144,7 @@ defmodule Web.AuthController do put_auth_state(conn, provider.id, {fragment, provider_identifier, redirect_params}) end - defp send_magic_link_email(conn, identity, redirect_params) do + defp send_email_otp(conn, identity, redirect_params) do # Nonce is the short part that is sent to the user in the email nonce = identity.provider_virtual_state.nonce diff --git a/elixir/apps/web/lib/web/live/settings/identity_providers/google_workspace/show.ex b/elixir/apps/web/lib/web/live/settings/identity_providers/google_workspace/show.ex index 18c8fee18..b470f979d 100644 --- a/elixir/apps/web/lib/web/live/settings/identity_providers/google_workspace/show.ex +++ b/elixir/apps/web/lib/web/live/settings/identity_providers/google_workspace/show.ex @@ -38,7 +38,7 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.Show do <.section> <:title> - Identity Provider <%= @provider.name %> + Identity Provider: <%= @provider.name %> (disabled) (deleted) diff --git a/elixir/apps/web/lib/web/live/settings/identity_providers/jumpcloud/show.ex b/elixir/apps/web/lib/web/live/settings/identity_providers/jumpcloud/show.ex index ab5cc06b7..624973cb5 100644 --- a/elixir/apps/web/lib/web/live/settings/identity_providers/jumpcloud/show.ex +++ b/elixir/apps/web/lib/web/live/settings/identity_providers/jumpcloud/show.ex @@ -41,7 +41,7 @@ defmodule Web.Settings.IdentityProviders.JumpCloud.Show do <.section> <:title> - Identity Provider <%= @provider.name %> + Identity Provider: <%= @provider.name %> (disabled) (deleted) diff --git a/elixir/apps/web/lib/web/live/settings/identity_providers/microsoft_entra/show.ex b/elixir/apps/web/lib/web/live/settings/identity_providers/microsoft_entra/show.ex index e979bb6a9..f48b8d35d 100644 --- a/elixir/apps/web/lib/web/live/settings/identity_providers/microsoft_entra/show.ex +++ b/elixir/apps/web/lib/web/live/settings/identity_providers/microsoft_entra/show.ex @@ -38,7 +38,7 @@ defmodule Web.Settings.IdentityProviders.MicrosoftEntra.Show do <.section> <:title> - Identity Provider <%= @provider.name %> + Identity Provider: <%= @provider.name %> (disabled) (deleted) diff --git a/elixir/apps/web/lib/web/live/settings/identity_providers/okta/show.ex b/elixir/apps/web/lib/web/live/settings/identity_providers/okta/show.ex index a71785840..6cc4b5c22 100644 --- a/elixir/apps/web/lib/web/live/settings/identity_providers/okta/show.ex +++ b/elixir/apps/web/lib/web/live/settings/identity_providers/okta/show.ex @@ -38,7 +38,7 @@ defmodule Web.Settings.IdentityProviders.Okta.Show do <.section> <:title> - Identity Provider <%= @provider.name %> + Identity Provider: <%= @provider.name %> (disabled) (deleted) diff --git a/elixir/apps/web/lib/web/live/settings/identity_providers/openid_connect/show.ex b/elixir/apps/web/lib/web/live/settings/identity_providers/openid_connect/show.ex index 00df7d6b1..514a24069 100644 --- a/elixir/apps/web/lib/web/live/settings/identity_providers/openid_connect/show.ex +++ b/elixir/apps/web/lib/web/live/settings/identity_providers/openid_connect/show.ex @@ -33,7 +33,7 @@ defmodule Web.Settings.IdentityProviders.OpenIDConnect.Show do <.section> <:title> - Identity Provider <%= @provider.name %> + Identity Provider: <%= @provider.name %> (disabled) (deleted) diff --git a/elixir/apps/web/lib/web/live/settings/identity_providers/system/show.ex b/elixir/apps/web/lib/web/live/settings/identity_providers/system/show.ex index 086ec7b1c..d5effc23a 100644 --- a/elixir/apps/web/lib/web/live/settings/identity_providers/system/show.ex +++ b/elixir/apps/web/lib/web/live/settings/identity_providers/system/show.ex @@ -33,7 +33,7 @@ defmodule Web.Settings.IdentityProviders.System.Show do <.section> <:title> - Identity Provider <%= @provider.name %> + Identity Provider: <%= @provider.name %> (disabled) (deleted) diff --git a/elixir/apps/web/lib/web/live/sign_in.ex b/elixir/apps/web/lib/web/live/sign_in.ex index 52985c2d6..f9270e3a1 100644 --- a/elixir/apps/web/lib/web/live/sign_in.ex +++ b/elixir/apps/web/lib/web/live/sign_in.ex @@ -204,7 +204,7 @@ defmodule Web.SignIn do ~H""" <.form for={@email_form} - action={~p"/#{@account}/sign_in/providers/#{@provider.id}/request_magic_link"} + action={~p"/#{@account}/sign_in/providers/#{@provider.id}/request_email_otp"} class="space-y-4 lg:space-y-6" id="email_form" phx-update="ignore" diff --git a/elixir/apps/web/lib/web/live/sign_in/email.ex b/elixir/apps/web/lib/web/live/sign_in/email.ex index b8273120d..c7282121e 100644 --- a/elixir/apps/web/lib/web/live/sign_in/email.ex +++ b/elixir/apps/web/lib/web/live/sign_in/email.ex @@ -158,7 +158,7 @@ defmodule Web.SignIn.Email do as={:email} class="inline" action={ - ~p"/#{@account_id_or_slug}/sign_in/providers/#{@provider_id}/request_magic_link?resend=true" + ~p"/#{@account_id_or_slug}/sign_in/providers/#{@provider_id}/request_email_otp?resend=true" } method="post" > diff --git a/elixir/apps/web/lib/web/live/sign_up.ex b/elixir/apps/web/lib/web/live/sign_up.ex index 6831831bf..0256e4a81 100644 --- a/elixir/apps/web/lib/web/live/sign_up.ex +++ b/elixir/apps/web/lib/web/live/sign_up.ex @@ -180,7 +180,7 @@ defmodule Web.SignUp do id="resend-email" as={:email} class="inline" - action={~p"/#{@account}/sign_in/providers/#{@provider}/request_magic_link"} + action={~p"/#{@account}/sign_in/providers/#{@provider}/request_email_otp"} method="post" > <.input diff --git a/elixir/apps/web/lib/web/router.ex b/elixir/apps/web/lib/web/router.ex index 3089764e7..c73effce1 100644 --- a/elixir/apps/web/lib/web/router.ex +++ b/elixir/apps/web/lib/web/router.ex @@ -93,7 +93,7 @@ defmodule Web.Router do post "/verify_credentials", AuthController, :verify_credentials # Email - post "/request_magic_link", AuthController, :request_magic_link + post "/request_email_otp", AuthController, :request_email_otp get "/verify_sign_in_token", AuthController, :verify_sign_in_token # IdP diff --git a/elixir/apps/web/test/support/conn_case.ex b/elixir/apps/web/test/support/conn_case.ex index 9dc9a3365..fa01e6cfe 100644 --- a/elixir/apps/web/test/support/conn_case.ex +++ b/elixir/apps/web/test/support/conn_case.ex @@ -75,7 +75,7 @@ defmodule Web.ConnCase do |> Plug.Conn.assign(:subject, subject) end - def put_magic_link_auth_state( + def put_email_auth_state( conn, account, %{adapter: :email} = provider, @@ -86,7 +86,7 @@ defmodule Web.ConnCase do Map.merge(%{"email" => %{"provider_identifier" => identity.provider_identifier}}, params) redirected_conn = - post(conn, ~p"/#{account}/sign_in/providers/#{provider.id}/request_magic_link", params) + post(conn, ~p"/#{account}/sign_in/providers/#{provider.id}/request_email_otp", params) assert_received {:email, email} [_match, secret] = Regex.run(~r/secret=([^&\n]*)/, email.text_body) @@ -136,7 +136,7 @@ defmodule Web.ConnCase do ) redirected_conn = - post(conn, ~p"/#{account}/sign_in/providers/#{provider.id}/request_magic_link", params) + post(conn, ~p"/#{account}/sign_in/providers/#{provider.id}/request_email_otp", params) assert_received {:email, email} [_match, secret] = Regex.run(~r/secret=([^&\n]*)/, email.text_body) diff --git a/elixir/apps/web/test/web/controllers/auth_controller_test.exs b/elixir/apps/web/test/web/controllers/auth_controller_test.exs index b72e497a0..121abb5e1 100644 --- a/elixir/apps/web/test/web/controllers/auth_controller_test.exs +++ b/elixir/apps/web/test/web/controllers/auth_controller_test.exs @@ -323,7 +323,7 @@ defmodule Web.AuthControllerTest do end end - describe "request_magic_link/2" do + describe "request_email_otp/2" do test "sends a login link to the user email", %{conn: conn} do account = Fixtures.Accounts.create_account() provider = Fixtures.Auth.create_email_provider(account: account) @@ -332,7 +332,7 @@ defmodule Web.AuthControllerTest do conn = post( conn, - ~p"/#{provider.account_id}/sign_in/providers/#{provider.id}/request_magic_link", + ~p"/#{provider.account_id}/sign_in/providers/#{provider.id}/request_email_otp", %{ "email" => %{ "provider_identifier" => identity.provider_identifier @@ -362,7 +362,7 @@ defmodule Web.AuthControllerTest do identity = Fixtures.Auth.create_identity(account: account, provider: provider) for _ <- 1..3 do - post(conn, ~p"/#{account}/sign_in/providers/#{provider}/request_magic_link", %{ + post(conn, ~p"/#{account}/sign_in/providers/#{provider}/request_email_otp", %{ "email" => %{ "provider_identifier" => identity.provider_identifier } @@ -373,7 +373,7 @@ defmodule Web.AuthControllerTest do end) end - post(conn, ~p"/#{account}/sign_in/providers/#{provider}/request_magic_link", %{ + post(conn, ~p"/#{account}/sign_in/providers/#{provider}/request_email_otp", %{ "email" => %{ "provider_identifier" => identity.provider_identifier } @@ -390,7 +390,7 @@ defmodule Web.AuthControllerTest do conn = post( conn, - ~p"/#{provider.account_id}/sign_in/providers/#{provider.id}/request_magic_link", + ~p"/#{provider.account_id}/sign_in/providers/#{provider.id}/request_email_otp", %{ "as" => "client", "nonce" => "NONCE", @@ -425,7 +425,7 @@ defmodule Web.AuthControllerTest do conn = post( conn, - ~p"/#{account.id}/sign_in/providers/#{provider_id}/request_magic_link", + ~p"/#{account.id}/sign_in/providers/#{provider_id}/request_email_otp", %{"email" => %{"provider_identifier" => "foo@bar.com"}} ) @@ -440,7 +440,7 @@ defmodule Web.AuthControllerTest do conn = post( conn, - ~p"/#{account.id}/sign_in/providers/#{provider_id}/request_magic_link", + ~p"/#{account.id}/sign_in/providers/#{provider_id}/request_email_otp", %{"email" => %{"provider_identifier" => "foo"}} ) @@ -455,7 +455,7 @@ defmodule Web.AuthControllerTest do conn = post( conn, - ~p"/#{account.id}/sign_in/providers/#{provider.id}/request_magic_link", + ~p"/#{account.id}/sign_in/providers/#{provider.id}/request_email_otp", %{"email" => %{"provider_identifier" => "foo@bar"}} ) @@ -480,7 +480,7 @@ defmodule Web.AuthControllerTest do actor = Fixtures.Actors.create_actor(type: :account_admin_user, account: account) identity = Fixtures.Auth.create_identity(account: account, provider: provider, actor: actor) - {conn_with_cookie, secret} = put_magic_link_auth_state(conn, account, provider, identity) + {conn_with_cookie, secret} = put_email_auth_state(conn, account, provider, identity) %{ account: account, @@ -596,7 +596,7 @@ defmodule Web.AuthControllerTest do } {conn_with_cookie, _secret} = - put_magic_link_auth_state(conn, account, provider, identity, redirect_params) + put_email_auth_state(conn, account, provider, identity, redirect_params) conn = conn_with_cookie @@ -679,7 +679,7 @@ defmodule Web.AuthControllerTest do } {conn_with_cookie, secret} = - put_magic_link_auth_state(conn, account, provider, identity, redirect_params) + put_email_auth_state(conn, account, provider, identity, redirect_params) conn = conn_with_cookie @@ -1233,7 +1233,7 @@ defmodule Web.AuthControllerTest do provider: provider ) - {conn, secret} = put_magic_link_auth_state(conn, account, provider, identity) + {conn, secret} = put_email_auth_state(conn, account, provider, identity) authorized_conn = conn diff --git a/elixir/apps/web/test/web/live/sign_in/email_test.exs b/elixir/apps/web/test/web/live/sign_in/email_test.exs index b921bb300..3ed8f801d 100644 --- a/elixir/apps/web/test/web/live/sign_in/email_test.exs +++ b/elixir/apps/web/test/web/live/sign_in/email_test.exs @@ -27,7 +27,7 @@ defmodule Web.SignIn.EmailTest do identity: identity, conn: conn } do - {conn, _secret} = put_magic_link_auth_state(conn, account, provider, identity) + {conn, _secret} = put_email_auth_state(conn, account, provider, identity) signed_provider_identifier = Plug.Crypto.sign( @@ -53,7 +53,7 @@ defmodule Web.SignIn.EmailTest do identity: identity, conn: conn } do - {conn, secret} = put_magic_link_auth_state(conn, account, provider, identity) + {conn, secret} = put_email_auth_state(conn, account, provider, identity) signed_provider_identifier = Plug.Crypto.sign( @@ -99,7 +99,7 @@ defmodule Web.SignIn.EmailTest do "redirect_to" => "/foo" } - {conn, secret} = put_magic_link_auth_state(conn, account, provider, identity, redirect_params) + {conn, secret} = put_email_auth_state(conn, account, provider, identity, redirect_params) signed_provider_identifier = Plug.Crypto.sign( @@ -139,7 +139,7 @@ defmodule Web.SignIn.EmailTest do identity: identity, conn: conn } do - {conn, _secret} = put_magic_link_auth_state(conn, account, provider, identity) + {conn, _secret} = put_email_auth_state(conn, account, provider, identity) signed_provider_identifier = Plug.Crypto.sign( diff --git a/website/src/app/page.tsx b/website/src/app/page.tsx index 5dbf0c92e..f14f31611 100644 --- a/website/src/app/page.tsx +++ b/website/src/app/page.tsx @@ -714,7 +714,7 @@ export default function Page() {
  • - Authenticate with Magic link or OIDC + Authenticate with Email OTP or OIDC