Reduce noise in 2FA enforce notifications and update docs link (#5869)

* Do not send email notification to users who already enabled 2FA

* Update docs link

* Improve email notification assertion
This commit is contained in:
Adrian Gruntkowski 2025-11-05 09:05:41 +01:00 committed by GitHub
parent af7dd46458
commit 1a5eba85e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 8 deletions

View File

@ -334,7 +334,7 @@ defmodule Plausible.Teams do
team
|> Teams.Memberships.all(exclude_guests?: true)
|> Enum.each(fn membership ->
if membership.user.id != user.id do
if membership.user.id != user.id and not Auth.TOTP.enabled?(membership.user) do
team
|> PlausibleWeb.Email.force_2fa_enabled(membership.user, user)
|> Plausible.Mailer.deliver_later()

View File

@ -43,7 +43,7 @@
session: %{"mode" => "team-management"}
)}
</.tile>
<.tile :if={@current_team_role == :owner} docs="2fa">
<.tile :if={@current_team_role == :owner} docs="2fa#require-all-team-members-to-enable-2fa">
<:title>
<a id="force-2fa">Force Two-Factor Authentication (2FA)</a>
</:title>

View File

@ -1749,20 +1749,38 @@ defmodule PlausibleWeb.SettingsControllerTest do
member1 = add_member(team, role: :viewer)
member2 = add_member(team, role: :owner)
member_with_2fa = add_member(team, role: :editor)
# enable 2FA
{:ok, member_with_2fa, _} = Plausible.Auth.TOTP.initiate(member_with_2fa)
code = NimbleTOTP.verification_code(member_with_2fa.totp_secret)
{:ok, _member_with_2fa, _} = Plausible.Auth.TOTP.enable(member_with_2fa, code)
guest = add_guest(site, role: :viewer)
conn = post(conn, Routes.settings_path(conn, :enable_team_force_2fa))
assert redirected_to(conn, 302) == Routes.settings_path(conn, :team_general)
assert_email_delivered_with(
subject: "Your team now requires 2FA",
to: [nil: member1.email]
)
# The email come in order in which they are sent.
# As the logic sending them does not force any order,
# we have to match them in order-independent way.
Enum.reduce(1..2, [member1.email, member2.email], fn _, emails ->
assert assert_delivered_email_matches(%{
subject: "Your team now requires 2FA",
to: [{_, email}]
})
assert_email_delivered_with(
assert email in emails
List.delete(emails, email)
end)
# member with 2FA already enabled is not notified
refute_email_delivered_with(
subject: "Your team now requires 2FA",
to: [nil: member2.email]
to: [nil: member_with_2fa.email]
)
# guests are not notified because they are not affected