diff --git a/docs/operations.md b/docs/operations.md index f660e3c..a077a75 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -387,6 +387,9 @@ idempotence key, redacts rejected recipient addresses from returned errors, and uses only HTTPS. The provider documents the endpoint, `X-API-KEY` header, response shape, and one-minute/64-character idempotence-key behavior in its [Web API reference](https://godocs.unisender.ru/web-api-ref). +Every request explicitly sets `track_links` and `track_read` to `0`; UniSender +Go otherwise enables both by default. The provider account must be allowed to +honour those values, so verify a delivered message's raw HTML before launch. ## Isolated restore drill diff --git a/docs/verification.md b/docs/verification.md index 648e106..9633b3f 100644 --- a/docs/verification.md +++ b/docs/verification.md @@ -1114,37 +1114,46 @@ availability, or target-server capacity. filtering occurs. - `WhoNeedHelp.Email.UnisenderGoAdapter` now maps the application's existing Swoosh messages to the provider's HTTPS `email/send.json` contract. Six - focused tests passed for the exact request shape and API-key header, success, - redacted recipient rejection, structured API errors, invalid responses, and - rejection of unsupported or provider-invalid messages before network I/O. + focused tests passed for the exact request shape (including explicit + `track_read=0` and `track_links=0`) and API-key header, success, redacted + recipient rejection, structured API errors, invalid responses, and rejection + of unsupported or provider-invalid messages before network I/O. Runtime configuration and production environment validation can select either `smtp` or `unisender_go` without requiring SMTP settings in API mode. -- UniSender Go's account settings were saved with read/open tracking and link - tracking disabled, then reloaded and observed still disabled. The provider's - unsubscribe-link setting remains enabled and locked; disabling it requires - provider approval and has not been claimed. -- A real email has not yet been submitted through the new adapter. The sending - domain's UniSender Go verification/DKIM records were issued but are not yet - present in authoritative DNS, so end-to-end delivery remains unproven. +- Authoritative DNS and the provider UI both showed the sending domain as + verified with DKIM active, while the delegated link domain showed configured. + A second real Web API message was accepted for one recipient with no rejected + recipients and reached Gmail's Inbox after one second. Gmail's original + message view reported SPF PASS, DKIM PASS with `d=whoneedhelp.com` and + selector `gokey`, and DMARC PASS. +- The delivered MIME still contained the provider's one-pixel + `go2_read_tracker` even though the request explicitly supplied + `track_read=0` and `track_links=0`. UniSender Go documents that honoring those + zero values, and using `skip_unsubscribe=1`, requires provider approval. A + support request covering all three permissions was sent to the official + support address from the account mailbox. Privacy-disable behavior and + unsubscribe removal remain unverified until the provider enables them and a + new delivered MIME is inspected. ## Known work before a public production launch - Replace the temporary staging origin with the production-owned domain and production infrastructure. The temporary origin is available only while the workstation, Compose stack, VPN path, gateway, and their networks are up. -- Create a production Android signing identity, publish - `/.well-known/assetlinks.json` for the final application ID/fingerprint if - verified App Links are wanted, and complete store policy/release work. +- Confirm the final Android application ID before creating its Play Console + listing, publish `/.well-known/assetlinks.json` for that ID and the final + signing fingerprint if verified App Links are wanted, and complete store + policy/release work. A dedicated upload key and signed APK/AAB have been + created and verified locally, but no Play application has been registered. - Operate PostgreSQL/PostGIS with off-site backups, recovery testing, monitoring, and the availability model selected for real usage. -- Publish and verify the issued UniSender Go SPF, DKIM, domain-validation, - DMARC, and link-domain DNS records, then exercise registration and magic-link - delivery through the selected HTTPS provider to a real mailbox. -- Create a Google OAuth Web client for the final owned HTTPS origin, configure - its exact `/auth/google/callback` redirect, and exercise registration, - sign-in, and settings linking against Google if Google authentication is to - be enabled. The feature remains disabled when both credentials are empty. +- After provider approval, verify that delivered MIME contains neither open nor + link tracking and omits the unsubscribe block, then exercise registration and + magic-link delivery through the deployed application to a real mailbox. +- Deploy the already configured production and staging Google OAuth clients, + then exercise registration, sign-in, and settings linking against Google on + their exact HTTPS callback origins. - Configure and verify a real mobile push provider and device-token lifecycle if native push is required. The provider-neutral HTTP boundary and product jobs are tested; FCM/APNs device delivery is not. diff --git a/lib/who_need_help/email/unisender_go_adapter.ex b/lib/who_need_help/email/unisender_go_adapter.ex index c8bff82..66779b8 100644 --- a/lib/who_need_help/email/unisender_go_adapter.ex +++ b/lib/who_need_help/email/unisender_go_adapter.ex @@ -93,6 +93,8 @@ defmodule WhoNeedHelp.Email.UnisenderGoAdapter do "from_email" => elem(email.from, 1), "from_name" => elem(email.from, 0), "body" => message_body(email), + "track_links" => 0, + "track_read" => 0, "idempotence_key" => idempotence_key(email) } |> maybe_put_reply_to(email.reply_to) diff --git a/test/who_need_help/email/unisender_go_adapter_test.exs b/test/who_need_help/email/unisender_go_adapter_test.exs index 676a64b..b9e8102 100644 --- a/test/who_need_help/email/unisender_go_adapter_test.exs +++ b/test/who_need_help/email/unisender_go_adapter_test.exs @@ -76,7 +76,9 @@ defmodule WhoNeedHelp.Email.UnisenderGoAdapterTest do "recipients" => [%{"email" => "helper@example.com"}], "reply_to" => "support@whoneedhelp.com", "reply_to_name" => "Support", - "subject" => "Confirmation instructions" + "subject" => "Confirmation instructions", + "track_links" => 0, + "track_read" => 0 } } end