Skip to content

Links de email publicos multi tenant

luizkim edited this page Aug 6, 2026 · 1 revision

Links de e-mail públicos (confirmação de conta e recuperação de senha)

Documentação técnica do fluxo de montagem de URLs públicas enviadas por e-mail nos serviços de verificação de conta e recuperação de senha do módulo api-platform-users.

Contexto e problema

Em ambientes multi-tenant / white-label (ex.: app.lave-go.com), o e-mail de confirmação de cadastro (/confirm-account?hash=...&token=...) e o de redefinição de senha (/reset-password?...) devem apontar para o domínio do frontend do tenant, não para o host genérico da API (api.controleonline.com).

Antes da correção, a resolução de URL pública priorizava variáveis de ambiente globais (PUBLIC_APP_DOMAIN, MANAGER_APP, etc.), o que fazia com que tenants em produção recebessem links apontando para o domínio errado.

Regras de negócio

  1. O link deve ser navegável pelo usuário final no domínio do app do tenant (frontend).
  2. O domínio do tenant é obtido a partir da requisição atual (header app-domain, Origin, Referer, host, etc.) via DomainService.
  3. Variáveis de ambiente de domínio configurado são fallback, nunca a fonte primária quando existe domínio de requisição válido.
  4. Se o domínio resolvido parecer host de API (api.controleonline.com ou prefixo api.), e existir um domínio de frontend configurado que não seja API, prefere-se o frontend.
  5. Fallback final de segurança: admin.controleonline.com se nada for resolvido.
  6. A mesma lógica de resolução é usada por:
    • AccountVerificationService (confirmação de conta)
    • PasswordRecoveryService (recuperação de senha)

Onde vive a lógica

Serviço Método principal Arquivo
Confirmação de conta buildVerificationUrlresolvePublicAppUrl src/Service/AccountVerificationService.php
Recuperação de senha buildRecoveryUrlresolvePublicAppUrl src/Service/PasswordRecoveryService.php
Resolução de domínio da requisição getDomain / resolveRequestDomain api-platform-commonsrc/Service/DomainService.php

Ordem de resolução em resolvePublicAppUrl

  1. Domínio da requisição atual (DomainService::getDomain() — header app-domain, Origin, Referer, path, host).
  2. Domínio configurado via ENV / $_SERVER / getenv (PUBLIC_APP_DOMAIN, MANAGER_APP, APP_DOMAIN, ADMIN_APP_DOMAIN).
  3. Se o domínio obtido parecer host de API e existir domínio configurado de frontend, usa o configurado.
  4. Se vazio: admin.controleonline.com.
  5. Garante esquema https:// (ou http:// se já presente) e remove barra final.

Detecção de host de API

private function looksLikeApiHost(string $domain): bool
{
    // normaliza host e verifica api.controleonline.com ou prefixo "api."
}

Visões de app (APP_TYPE)

Visão Papel deste fluxo
SHOP / DELIVERY / SERVICE / POS (white-label) O frontend do tenant é a origem da requisição; o e-mail deve voltar para o mesmo domínio.
MANAGER / CRM / ADMIN Podem usar domínio configurado global ou do tenant logado.
API Nunca deve ser o destino do link do e-mail (o usuário final não autentica na API).

O módulo não decide o layout do e-mail nem a tela de confirmação no frontend; apenas monta a URL base + query string. A rota /confirm-account e /reset-password devem existir no frontend do tenant.

Contratos e dependências

  • Entrada: usuário (User), e-mail destinatário, hash/token gerados.
  • Saída: e-mail enviado via EmailService com HTML contendo o link absoluto.
  • Dependência transversal: DomainService (api-platform-common) e cabeçalhos de tenant propagados pela camada de API/gateway.
  • Configuração: variáveis PUBLIC_APP_DOMAIN / MANAGER_APP / APP_DOMAIN / ADMIN_APP_DOMAIN continuam úteis como fallback e para ambientes sem contexto de request (CLI, jobs).

Troubleshooting

Sintoma Causa provável Ação
Link aponta para api.controleonline.com Request sem app-domain / Origin / Referer e ENV aponta para API, ou lógica antiga priorizando ENV Garantir que a chamada de envio de e-mail ocorra em request com contexto do tenant; verificar deploy da correção em AccountVerificationService / PasswordRecoveryService
Link aponta para domínio genérico errado ENV global sobrescrevendo tenant Após a correção, request domain tem prioridade; validar header app-domain no proxy/gateway
Link sem esquema ou com barra final Resolução incompleta A função normaliza esquema e remove trailing slash

Referências de entrega

  • Issues: app-community#323 (redefinição de senha), app-community#324 (confirmação de conta)
  • Branch de correção: task-323 em api-platform-users
  • Commit de referência (preferência de request domain): fix: prefer request domain for password recovery and account verification links

Módulos relacionados

Módulo Relação
api-platform-common DomainService (fonte do domínio da requisição)
api-platform-users Serviços de verificação e recuperação
app-community / frontends white-label Rotas /confirm-account e /reset-password no SPA
api-community Home da API (fluxos transversais de autenticação)

Histórico

  • 2026-08-06: Documentação inicial após correção de prioridade request domain vs ENV (issues #323 / #324).