Avoid tracked links in authentication emails
This commit is contained in:
parent
e20bfca423
commit
dcac2fa0bc
|
|
@ -3346,6 +3346,27 @@ promoted.
|
|||
tracked primary button preserves the same privacy property, so replacing or
|
||||
disabling that tracked CTA remains an open provider/product decision.
|
||||
|
||||
# 2026-08-25 authentication-email no-anchor local verification
|
||||
|
||||
- The authentication HTML template now renders the one-time production URL as
|
||||
visible copy-and-paste text and contains no explicit `href` attribute. This
|
||||
removes the HTML action anchor that Brevo rewrote during the preceding
|
||||
production check; the text and multipart fallback remain direct application
|
||||
URLs. English, Russian, and Ukrainian catalog entries were updated together.
|
||||
- The focused notifier suite passed all four tests and explicitly asserted that
|
||||
the rendered HTML contains the direct URL and no `href`. Formatting passed.
|
||||
- The isolated full quality unit
|
||||
`codex-heavy-wnh-auth-email-quality-20260825-223236-3571086.service`
|
||||
completed successfully in 4 minutes 32.133 seconds with a 341.9 MiB memory
|
||||
peak and zero swap use. ExUnit reported 487 passing tests and every configured
|
||||
quality and security gate passed.
|
||||
- Exact post-run inspection found no container, network, volume, or temporary
|
||||
image carrying run identifier `20260825193236-3571714` or Compose project
|
||||
`wnh_quality_202608251932363571714`. This is local evidence only: production,
|
||||
the frozen hackathon test deployment, Caddy, and the public Git remote were
|
||||
not changed. The direct-action checklist item remains open until a newly
|
||||
delivered production message is inspected after an app-only release.
|
||||
|
||||
# 2026-08-21 connected-device Play delivery recheck
|
||||
|
||||
- The authorised physical device `72551e60` reported installed package
|
||||
|
|
|
|||
|
|
@ -168,21 +168,21 @@ defmodule WhoNeedHelp.Accounts.UserNotifier do
|
|||
<td style="padding:16px 32px 0;font-size:16px;line-height:1.6;color:#555b58;">#{escaped_introduction}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:24px 32px;">
|
||||
<a href="#{escaped_url}" style="display:inline-block;padding:13px 20px;border-radius:8px;background:#a93612;color:#ffffff;text-decoration:none;font-size:16px;font-weight:700;">#{escaped_action_label}</a>
|
||||
<td style="padding:24px 32px 8px;">
|
||||
<div style="font-size:14px;line-height:1.5;font-weight:700;color:#1d1d20;">#{escaped_action_label}</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 32px 8px;font-size:12px;line-height:1.5;color:#747a77;">#{escape_html(gettext("Copy and paste this secure address into your browser:"))}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 32px 24px;font-size:14px;line-height:1.55;word-break:break-all;color:#007d6b;">#{escaped_url}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 32px 8px;font-size:14px;line-height:1.55;color:#555b58;">#{escaped_expiry_note}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:8px 32px 0;font-size:14px;line-height:1.55;color:#555b58;">#{escaped_security_note}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:20px 32px 8px;font-size:12px;line-height:1.5;color:#747a77;">#{escape_html(gettext("If the button does not work, copy and paste this address into your browser:"))}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 32px 28px;font-size:12px;line-height:1.5;word-break:break-all;color:#007d6b;">#{escaped_url}</td>
|
||||
<td style="padding:8px 32px 28px;font-size:14px;line-height:1.55;color:#555b58;">#{escaped_security_note}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -6721,11 +6721,6 @@ msgstr ""
|
|||
msgid "If you did not create this account, you can safely ignore this email."
|
||||
msgstr ""
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:182
|
||||
#, elixir-autogen
|
||||
msgid "If the button does not work, copy and paste this address into your browser:"
|
||||
msgstr ""
|
||||
|
||||
#: lib/who_need_help_web/live/support_operation_live.ex:120
|
||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||
#, elixir-autogen, elixir-format
|
||||
|
|
@ -7872,3 +7867,8 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Enable Android notifications"
|
||||
msgstr ""
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:176
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Copy and paste this secure address into your browser:"
|
||||
msgstr ""
|
||||
|
|
|
|||
|
|
@ -6721,11 +6721,6 @@ msgstr "Confirm account"
|
|||
msgid "If you did not create this account, you can safely ignore this email."
|
||||
msgstr "If you did not create this account, you can safely ignore this email."
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:182
|
||||
#, elixir-autogen
|
||||
msgid "If the button does not work, copy and paste this address into your browser:"
|
||||
msgstr "If the button does not work, copy and paste this address into your browser:"
|
||||
|
||||
#: lib/who_need_help_web/live/support_operation_live.ex:120
|
||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||
#, elixir-autogen, elixir-format
|
||||
|
|
@ -7872,3 +7867,8 @@ msgstr "Android will request notification permission and securely register this
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Enable Android notifications"
|
||||
msgstr "Enable Android notifications"
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:176
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Copy and paste this secure address into your browser:"
|
||||
msgstr "Copy and paste this secure address into your browser:"
|
||||
|
|
|
|||
|
|
@ -6840,11 +6840,6 @@ msgstr "Подтвердить учётную запись"
|
|||
msgid "If you did not create this account, you can safely ignore this email."
|
||||
msgstr "Если вы не создавали эту учётную запись, просто проигнорируйте письмо."
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:182
|
||||
#, elixir-autogen
|
||||
msgid "If the button does not work, copy and paste this address into your browser:"
|
||||
msgstr "Если кнопка не работает, скопируйте этот адрес и вставьте его в браузер:"
|
||||
|
||||
#: lib/who_need_help_web/live/support_operation_live.ex:120
|
||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||
#, elixir-autogen, elixir-format
|
||||
|
|
@ -7992,3 +7987,8 @@ msgstr "Android запросит разрешение на уведомлени
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Enable Android notifications"
|
||||
msgstr "Включить уведомления Android"
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:176
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Copy and paste this secure address into your browser:"
|
||||
msgstr "Скопируйте этот безопасный адрес и вставьте его в браузер:"
|
||||
|
|
|
|||
|
|
@ -6834,11 +6834,6 @@ msgstr "Підтвердити обліковий запис"
|
|||
msgid "If you did not create this account, you can safely ignore this email."
|
||||
msgstr "Якщо ви не створювали цей обліковий запис, просто проігноруйте лист."
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:182
|
||||
#, elixir-autogen
|
||||
msgid "If the button does not work, copy and paste this address into your browser:"
|
||||
msgstr "Якщо кнопка не працює, скопіюйте цю адресу та вставте її у браузер:"
|
||||
|
||||
#: lib/who_need_help_web/live/support_operation_live.ex:120
|
||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||
#, elixir-autogen, elixir-format
|
||||
|
|
@ -7986,3 +7981,8 @@ msgstr "Android запросить дозвіл на сповіщення та
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Enable Android notifications"
|
||||
msgstr "Увімкнути сповіщення Android"
|
||||
|
||||
#: lib/who_need_help/accounts/user_notifier.ex:176
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Copy and paste this secure address into your browser:"
|
||||
msgstr "Скопіюйте цю безпечну адресу та вставте її у браузер:"
|
||||
|
|
|
|||
|
|
@ -21,10 +21,9 @@ defmodule WhoNeedHelp.Accounts.UserNotifierTest do
|
|||
refute email.text_body =~ user.email
|
||||
|
||||
assert email.html_body =~ "<title>Sign in to Who Need Help</title>"
|
||||
assert email.html_body =~ ~s(href="#{url}")
|
||||
assert email.html_body =~ "copy and paste this address into your browser"
|
||||
assert email.html_body =~ "Copy and paste this secure address into your browser"
|
||||
assert email.html_body =~ ~s(color:#007d6b;">#{url}</td>)
|
||||
assert length(Regex.scan(~r/href=/, email.html_body)) == 1
|
||||
refute email.html_body =~ "href="
|
||||
refute email.html_body =~ "<img"
|
||||
refute email.html_body =~ user.email
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user