feat(plataforma): tema de e-mail Athletic Map
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
# GERADO por scripts/tema_email_athleticmap.py — nao edite na mao.
|
||||
# Fonte: keycloak-theme/escolinha/email/
|
||||
#
|
||||
# O `items` do volume (ver 20-keycloak.yaml) desfaz o achatamento das
|
||||
# chaves: `template.ftl` vira `html/template.ftl` na montagem.
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: kc-email-athleticmapv2
|
||||
namespace: escolinha-prod
|
||||
annotations:
|
||||
# Mesmo motivo do tema de login: sem isto o ArgoCD guarda o
|
||||
# manifesto inteiro numa anotacao limitada a 256 KiB.
|
||||
argocd.argoproj.io/sync-options: ServerSideApply=true
|
||||
data:
|
||||
theme.properties: |-
|
||||
# O tema de E-MAIL do Athletic Map.
|
||||
#
|
||||
# `parent=base` e nao `keycloak`: o tema `keycloak` de e-mail nao acrescenta
|
||||
# nada ao `base` alem de recursos que nao usamos, e herdar dele traria um
|
||||
# template.ftl que este aqui substitui inteiro.
|
||||
#
|
||||
# Ao sobrescrever `template.ftl`, TODO e-mail do realm ganha a moldura da marca
|
||||
# — inclusive os que este tema nao reescreve (redefinicao de senha, verificacao
|
||||
# de e-mail). O corpo deles continua vindo do `base`, dentro da moldura nova.
|
||||
parent=base
|
||||
|
||||
# pt-BR primeiro: o cliente e brasileiro. O `en` fica porque o Keycloak cai
|
||||
# nele quando o navegador de quem recebe pede outra coisa, e um e-mail em
|
||||
# ingles e melhor do que um e-mail com as chaves cruas.
|
||||
locales=pt-BR,en
|
||||
template.ftl: |-
|
||||
<#--
|
||||
A moldura de TODO e-mail do realm.
|
||||
|
||||
── POR QUE TABELA, E NAO DIV ────────────────────────────────────────────────
|
||||
|
||||
Outlook no Windows renderiza com o motor do Word, que ignora `flex`, `grid` e
|
||||
boa parte de `margin`. Tabela aninhada com largura fixa e o unico layout que
|
||||
chega igual no Gmail, no Outlook e no app do celular. Nao e gosto antigo: e o
|
||||
que o cliente que acabou de pagar vai abrir.
|
||||
|
||||
── POR QUE ESTILO EM LINHA ──────────────────────────────────────────────────
|
||||
|
||||
Gmail REMOVE a tag <style> do <head>. Tudo que precisa valer vai em `style=`
|
||||
no proprio elemento.
|
||||
|
||||
── POR QUE A MARCA NAO E IMAGEM ─────────────────────────────────────────────
|
||||
|
||||
A tela de login embute o logo em data URI, e ali funciona. Em e-mail nao: o
|
||||
Gmail nao carrega `src="data:..."`, e o Outlook bloqueia imagem externa ate
|
||||
o leitor clicar em "exibir". As tres barras sao celulas com `bgcolor`, que
|
||||
todo cliente pinta, e o nome e texto — a marca chega inteira mesmo com as
|
||||
imagens desligadas.
|
||||
|
||||
Cores: as mesmas variaveis do login.ftl.
|
||||
laranja #F58220 · navy #0B2C3D · papel #F6F5F3 · linha #E7E5E1 · fraco #6B6B6B
|
||||
-->
|
||||
<#macro emailLayout>
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>${msg("emailTituloDaJanela")}</title>
|
||||
</head>
|
||||
<body style="margin:0; padding:0; background:#F6F5F3;">
|
||||
|
||||
<!-- A primeira linha do preview, no lugar de um trecho do HTML. -->
|
||||
<div style="display:none; max-height:0; overflow:hidden; opacity:0;">
|
||||
${msg("emailPreCabecalho")}
|
||||
</div>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"
|
||||
style="background:#F6F5F3; padding:32px 16px;">
|
||||
<tr>
|
||||
<td align="center">
|
||||
|
||||
<table role="presentation" width="600" cellpadding="0" cellspacing="0" border="0"
|
||||
style="width:600px; max-width:100%; background:#FFFFFF;
|
||||
border:1px solid #E7E5E1; border-radius:14px; overflow:hidden;
|
||||
font-family:'Inter','Segoe UI',system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;">
|
||||
|
||||
<!-- ── cabecalho ─────────────────────────────────────────────── -->
|
||||
<tr>
|
||||
<td style="background:#0B2C3D; padding:26px 32px;">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<!-- as tres barras -->
|
||||
<td style="padding-right:4px;">
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="5" height="14" bgcolor="#F58220"
|
||||
style="font-size:0; line-height:0;"> </td>
|
||||
<td width="4"> </td>
|
||||
<td width="5" height="20" bgcolor="#F58220"
|
||||
style="font-size:0; line-height:0;"> </td>
|
||||
<td width="4"> </td>
|
||||
<td width="5" height="26" bgcolor="#F58220"
|
||||
style="font-size:0; line-height:0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="padding-left:10px; color:#FFFFFF; font-size:19px;
|
||||
font-weight:700; letter-spacing:-0.2px;">
|
||||
Athletic Map
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- a fatia laranja, o mesmo corte diagonal da tela de login -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#F58220" style="font-size:0; line-height:0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- ── corpo ─────────────────────────────────────────────────── -->
|
||||
<tr>
|
||||
<td style="padding:36px 32px 8px 32px; color:#0B2C3D; font-size:16px; line-height:1.6;">
|
||||
<#nested>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- ── rodape ────────────────────────────────────────────────── -->
|
||||
<tr>
|
||||
<td style="padding:24px 32px 30px 32px;">
|
||||
<div style="border-top:1px solid #E7E5E1; padding-top:18px;
|
||||
color:#6B6B6B; font-size:12px; line-height:1.6;">
|
||||
${msg("emailRodapeAviso")}<br>
|
||||
<span style="color:#9C9A95;">${msg("emailRodapeAssinatura")}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</#macro>
|
||||
executeActions.ftl: |-
|
||||
<#--
|
||||
O e-mail que o cliente que ACABOU DE PAGAR recebe.
|
||||
|
||||
E o primeiro contato dele com o produto depois do cartao passar, e ate
|
||||
2026-09-24 ele chegava com o texto de fabrica do Keycloak: "Your administrator
|
||||
has just requested that you update your account". Nao ha administrador nenhum,
|
||||
ninguem pediu nada, e o cliente nao fala ingles.
|
||||
|
||||
── AS VARIAVEIS QUE O KEYCLOAK ENTREGA ──────────────────────────────────────
|
||||
|
||||
link o endereco de uso unico
|
||||
linkExpiration o prazo, em minutos
|
||||
linkExpirationFormatter formata o prazo por extenso ("12 horas")
|
||||
realmName o displayName do realm
|
||||
requiredActions a lista de acoes (UPDATE_PASSWORD, VERIFY_EMAIL...)
|
||||
user quem recebe
|
||||
|
||||
── POR QUE O BOTAO E UMA TABELA ─────────────────────────────────────────────
|
||||
|
||||
`<a>` com padding nao vira area clicavel no Outlook: ele so pinta o texto. A
|
||||
tabela com `bgcolor` e o <a> ocupando a celula inteira e o unico jeito de o
|
||||
botao ser um botao nos tres clientes.
|
||||
|
||||
── E POR QUE O LINK APARECE EM TEXTO TAMBEM ─────────────────────────────────
|
||||
|
||||
Cliente corporativo reescreve href para passar por filtro, e as vezes quebra.
|
||||
Com o endereco visivel, quem recebe consegue copiar e colar. Custa tres linhas
|
||||
e salva o cliente de ligar para o suporte no primeiro dia.
|
||||
-->
|
||||
<#assign acoes><#if requiredActions??><#list requiredActions><#items as a>${msg("requiredAction.${a}")}<#sep>, </#sep></#items></#list></#if></#assign>
|
||||
|
||||
<#import "template.ftl" as layout>
|
||||
<@layout.emailLayout>
|
||||
|
||||
<h1 style="margin:0 0 6px 0; font-size:26px; line-height:1.25; font-weight:700; color:#0B2C3D;">
|
||||
${msg("boasVindasTitulo")} <span style="color:#F58220;">${msg("boasVindasTituloDestaque")}</span>
|
||||
</h1>
|
||||
|
||||
<p style="margin:0 0 22px 0; color:#6B6B6B; font-size:15px;">
|
||||
${msg("boasVindasSubtitulo", realmName)}
|
||||
</p>
|
||||
|
||||
<p style="margin:0 0 26px 0;">
|
||||
${msg("boasVindasCorpo", acoes)}
|
||||
</p>
|
||||
|
||||
<!-- o botao -->
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px 0;">
|
||||
<tr>
|
||||
<td bgcolor="#F58220" style="border-radius:10px;">
|
||||
<a href="${link}"
|
||||
style="display:inline-block; padding:15px 30px; color:#FFFFFF;
|
||||
font-size:16px; font-weight:700; text-decoration:none;
|
||||
font-family:'Inter','Segoe UI',system-ui,Helvetica,Arial,sans-serif;">
|
||||
${msg("boasVindasBotao")} →
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0 0 24px 0; padding:14px 16px; background:#FFF5E8;
|
||||
border-left:3px solid #F58220; border-radius:0 8px 8px 0;
|
||||
color:#0B2C3D; font-size:14px; line-height:1.55;">
|
||||
${msg("boasVindasPrazo", linkExpirationFormatter(linkExpiration))}
|
||||
</p>
|
||||
|
||||
<p style="margin:0 0 6px 0; color:#6B6B6B; font-size:13px;">
|
||||
${msg("boasVindasLinkManual")}
|
||||
</p>
|
||||
<p style="margin:0 0 10px 0; font-size:13px; line-height:1.5; word-break:break-all;">
|
||||
<a href="${link}" style="color:#2563EB; text-decoration:underline;">${link}</a>
|
||||
</p>
|
||||
|
||||
</@layout.emailLayout>
|
||||
messages_pt_BR.properties: |-
|
||||
# Textos do e-mail do Athletic Map.
|
||||
#
|
||||
# ISO-8859-1 e o encoding que o Keycloak le aqui - em .properties, tudo fora do
|
||||
# Latin-1 precisa de \uXXXX. Acento comum (a, e, i, o, u com til/agudo/circunflexo)
|
||||
# passa direto; travessao, aspas curvas e emoji NAO passam, e viram simbolo torto
|
||||
# na caixa de quem recebe.
|
||||
#
|
||||
# Chave `{0}`, `{1}`... sao os argumentos na ordem em que o .ftl passa.
|
||||
|
||||
# -- o assunto ---------------------------------------------------------------
|
||||
# Sem "Update Your Account". O cliente acabou de pagar; o assunto diz o que ele
|
||||
# precisa fazer, e a marca aparece para ele reconhecer na lista.
|
||||
executeActionsSubject=Sua conta Athletic Map esta pronta
|
||||
|
||||
# -- a moldura ---------------------------------------------------------------
|
||||
emailTituloDaJanela=Athletic Map
|
||||
# O trecho que Gmail e Outlook mostram ao lado do assunto, antes de abrir.
|
||||
emailPreCabecalho=Falta um passo para voce entrar: defina sua senha de acesso.
|
||||
emailRodapeAviso=Se voce nao reconhece este pedido, pode ignorar esta mensagem \u2014 nada muda na sua conta.
|
||||
emailRodapeAssinatura=Athletic Map \u2014 gestao para escolinhas esportivas
|
||||
|
||||
# -- o corpo das boas-vindas -------------------------------------------------
|
||||
boasVindasTitulo=Sua conta esta
|
||||
boasVindasTituloDestaque=pronta!
|
||||
# {0} = nome do realm (displayName)
|
||||
boasVindasSubtitulo=Acesso a {0}
|
||||
# {0} = as acoes pedidas, ja traduzidas ("Atualizar senha")
|
||||
boasVindasCorpo=Falta um passo para voce comecar: {0}. Clique no botao abaixo e leve menos de um minuto.
|
||||
boasVindasBotao=Definir minha senha
|
||||
# {0} = o prazo por extenso
|
||||
boasVindasPrazo=Este link vale por {0} e pode ser usado uma vez so. Depois disso, peca outro na tela de acesso, em "Esqueceu sua senha?".
|
||||
boasVindasLinkManual=Se o botao nao funcionar, copie e cole este endereco no navegador:
|
||||
|
||||
# -- as acoes, em portugues --------------------------------------------------
|
||||
# O Keycloak traduz estas chaves para montar a lista do corpo. Sem elas, o
|
||||
# cliente brasileiro le "Update Password" no meio de uma frase em portugues.
|
||||
requiredAction.UPDATE_PASSWORD=definir sua senha
|
||||
requiredAction.VERIFY_EMAIL=confirmar seu e-mail
|
||||
requiredAction.UPDATE_PROFILE=completar seu cadastro
|
||||
requiredAction.CONFIGURE_TOTP=configurar a verificacao em duas etapas
|
||||
requiredAction.TERMS_AND_CONDITIONS=aceitar os termos de uso
|
||||
requiredAction.CONFIGURE_RECOVERY_AUTHN_CODES=gerar seus codigos de recuperacao
|
||||
messages_en.properties: |-
|
||||
# O MESMO conjunto de chaves, em ingles.
|
||||
#
|
||||
# Nao e capricho: o Keycloak escolhe o locale pelo idioma de quem recebe, e se
|
||||
# ele cair no `en` sem estas chaves o e-mail sai com o NOME DELAS no lugar do
|
||||
# texto - "boasVindasTitulo" literal no corpo. Um arquivo faltando aqui nao
|
||||
# quebra nada em teste e estraga o primeiro e-mail de um cliente estrangeiro.
|
||||
|
||||
executeActionsSubject=Your Athletic Map account is ready
|
||||
|
||||
emailTituloDaJanela=Athletic Map
|
||||
emailPreCabecalho=One step left: set your password.
|
||||
emailRodapeAviso=If you did not expect this, you can ignore this message \u2014 nothing changes in your account.
|
||||
emailRodapeAssinatura=Athletic Map \u2014 management for sports schools
|
||||
|
||||
boasVindasTitulo=Your account is
|
||||
boasVindasTituloDestaque=ready!
|
||||
boasVindasSubtitulo=Access to {0}
|
||||
boasVindasCorpo=One step left before you start: {0}. Click the button below \u2014 it takes less than a minute.
|
||||
boasVindasBotao=Set my password
|
||||
boasVindasPrazo=This link is valid for {0} and can be used once. After that, request a new one on the sign-in screen, under "Forgot your password?".
|
||||
boasVindasLinkManual=If the button does not work, copy and paste this address into your browser:
|
||||
|
||||
requiredAction.UPDATE_PASSWORD=set your password
|
||||
requiredAction.VERIFY_EMAIL=confirm your e-mail
|
||||
requiredAction.UPDATE_PROFILE=complete your profile
|
||||
requiredAction.CONFIGURE_TOTP=set up two-step verification
|
||||
requiredAction.TERMS_AND_CONDITIONS=accept the terms of use
|
||||
requiredAction.CONFIGURE_RECOVERY_AUTHN_CODES=generate your recovery codes
|
||||
Reference in New Issue
Block a user