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
|
tracked primary button preserves the same privacy property, so replacing or
|
||||||
disabling that tracked CTA remains an open provider/product decision.
|
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
|
# 2026-08-21 connected-device Play delivery recheck
|
||||||
|
|
||||||
- The authorised physical device `72551e60` reported installed package
|
- 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>
|
<td style="padding:16px 32px 0;font-size:16px;line-height:1.6;color:#555b58;">#{escaped_introduction}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding:24px 32px;">
|
<td style="padding:24px 32px 8px;">
|
||||||
<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>
|
<div style="font-size:14px;line-height:1.5;font-weight:700;color:#1d1d20;">#{escaped_action_label}</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<tr>
|
||||||
<td style="padding:0 32px 8px;font-size:14px;line-height:1.55;color:#555b58;">#{escaped_expiry_note}</td>
|
<td style="padding:0 32px 8px;font-size:14px;line-height:1.55;color:#555b58;">#{escaped_expiry_note}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding:8px 32px 0;font-size:14px;line-height:1.55;color:#555b58;">#{escaped_security_note}</td>
|
<td style="padding:8px 32px 28px;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>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
||||||
|
|
@ -6721,11 +6721,6 @@ msgstr ""
|
||||||
msgid "If you did not create this account, you can safely ignore this email."
|
msgid "If you did not create this account, you can safely ignore this email."
|
||||||
msgstr ""
|
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_operation_live.ex:120
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -7872,3 +7867,8 @@ msgstr ""
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Enable Android notifications"
|
msgid "Enable Android notifications"
|
||||||
msgstr ""
|
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."
|
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."
|
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_operation_live.ex:120
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -7872,3 +7867,8 @@ msgstr "Android will request notification permission and securely register this
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Enable Android notifications"
|
msgid "Enable Android notifications"
|
||||||
msgstr "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."
|
msgid "If you did not create this account, you can safely ignore this email."
|
||||||
msgstr "Если вы не создавали эту учётную запись, просто проигнорируйте письмо."
|
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_operation_live.ex:120
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -7992,3 +7987,8 @@ msgstr "Android запросит разрешение на уведомлени
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Enable Android notifications"
|
msgid "Enable Android notifications"
|
||||||
msgstr "Включить уведомления Android"
|
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."
|
msgid "If you did not create this account, you can safely ignore this email."
|
||||||
msgstr "Якщо ви не створювали цей обліковий запис, просто проігноруйте лист."
|
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_operation_live.ex:120
|
||||||
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
#: lib/who_need_help_web/live/support_operations_live.ex:240
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -7986,3 +7981,8 @@ msgstr "Android запросить дозвіл на сповіщення та
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Enable Android notifications"
|
msgid "Enable Android notifications"
|
||||||
msgstr "Увімкнути сповіщення Android"
|
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
|
refute email.text_body =~ user.email
|
||||||
|
|
||||||
assert email.html_body =~ "<title>Sign in to Who Need Help</title>"
|
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 secure address into your browser"
|
||||||
assert email.html_body =~ "copy and paste this address into your browser"
|
|
||||||
assert email.html_body =~ ~s(color:#007d6b;">#{url}</td>)
|
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 =~ "<img"
|
||||||
refute email.html_body =~ user.email
|
refute email.html_body =~ user.email
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user