feat(bimi): logotipo do dominio validado, alojado e publicado no DNS
A foto de perfil nao viaja: nem o Gmail nem o Outlook leem uma imagem por utilizador do servidor de quem envia, e nao existe protocolo que o permita. O avatar que esses mostram vem dos contactos de quem recebe ou da conta Google ou Microsoft do remetente. O que eles leem e BIMI, que e por dominio. Fica implementado: validacao, alojamento e o registo. O validador reporta todas as violacoes de uma vez, e nao a primeira. Um receptor que recusa a marca nao explica nada -- simplesmente nao desenha -- por isso descobrir as regras uma viagem de cada vez seria a pior maneira possivel de aprender este formato. Sao verificados o baseProfile e a versao que os receptores procuram, o viewBox quadrado (uma marca nao quadrada e cortada de forma diferente por cada cliente), exactamente um title, e a ausencia de tudo o que seja activo ou externo: script, handlers de evento, links, imagens rasterizadas, animacoes e referencias para fora do documento. O registo so e publicado quando ha mesmo uma marca guardada. Um registo que aponta para um logotipo inexistente e pior do que nenhum, porque o receptor para de procurar assim que encontra um. O logotipo e servido aberto, porque quem o vai buscar sao os fornecedores de correio a avaliar uma mensagem e esses nunca terao sessao aqui. Fica escrito no README que o Gmail e o Outlook so desenham a marca com um VMC, e o painel avisa quando nao ha nenhum configurado. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fcfee6a3f9
commit
6a602ab88f
16 files changed
+955
-5
No files matched your search
@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"lambdamail/protocols/internal/infrastructure/postgres"
|
||||
httppresentation "lambdamail/protocols/internal/presentation/http"
|
||||
)
|
||||
|
||||
// bimiStore adapts the repository to the shape the HTTP layer asks for, so
|
||||
// that layer does not import the database package.
|
||||
type bimiStore struct {
|
||||
repo *postgres.BimiRepository
|
||||
}
|
||||
|
||||
func (s bimiStore) Save(ctx context.Context, domain string, svg []byte, vmcURL string) (string, error) {
|
||||
return s.repo.Save(ctx, domain, svg, vmcURL)
|
||||
}
|
||||
|
||||
func (s bimiStore) Load(ctx context.Context, domain string) (*httppresentation.BimiLogo, error) {
|
||||
logo, err := s.repo.Load(ctx, domain)
|
||||
if err != nil || logo == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &httppresentation.BimiLogo{SVG: logo.SVG, ETag: logo.ETag, VmcURL: logo.VmcURL}, nil
|
||||
}
|
||||
|
||||
func (s bimiStore) Delete(ctx context.Context, domain string) error {
|
||||
return s.repo.Delete(ctx, domain)
|
||||
}
|
||||
Reference in new issue
Block a user