Skip to content

Repository files navigation

📧 Delphi Email & OAuth2 Hub

Arquitetura completa em Delphi + Indy para envio e leitura de e-mails com suporte a SMTP, IMAP, POP3, Microsoft Graph API, OAuth2, SSL/TLS, STARTTLS, anexos, logs e geração de arquivos .eml.


📌 Sumário


Visão Geral

Este projeto implementa uma arquitetura desacoplada para trabalhar com e-mail e autenticação OAuth2 em Delphi.

Ele permite:

  • Enviar e-mails via SMTP.
  • Enviar e-mails via Microsoft Graph API quando usado o fluxo Client Credentials.
  • Autenticar usando múltiplos fluxos OAuth2.
  • Ler e-mails via:
    • Microsoft Graph API
    • IMAP
    • POP3
  • Trabalhar com anexos.
  • Suportar SSL/TLS e STARTTLS.
  • Persistir configurações em arquivo INI.
  • Gerar arquivos .eml para resposta com threading, citação e anexos.
  • Exibir logs detalhados na interface e em arquivos de diagnóstico.

Recursos

Envio

  • Envio via TIdSMTP.
  • Suporte a autenticação tradicional usuário/senha.
  • Suporte a autenticação OAuth2 via XOAUTH2.
  • Suporte a SSL/TLS implícito.
  • Suporte a STARTTLS.
  • Envio de múltiplos anexos.
  • Suporte a mensagens com Content-Type configurável.
  • Envio via Microsoft Graph API para cenários App-Only / Daemon.

OAuth2

Fluxos implementados:

  • Traditional User/Password
  • Authorization Code
  • Authorization Code + PKCE
  • Device Code
  • Implicit
  • Resource Owner Password Credentials - ROPC
  • Client Credentials
  • Refresh Token

Leitura

  • Leitura de e-mails via Microsoft Graph API.
  • Leitura via IMAP.
  • Leitura via POP3.
  • Listagem de pastas/caixas de correio.
  • Preview de mensagens.
  • Visualização de remetente, destinatários, CC, BCC, Reply-To.
  • Flags:
    • Lida
    • Não lida
    • Sinalizada
    • Respondida
    • Rascunho
  • Prioridade.
  • Anexos.
  • Anexos inline.
  • Corpo texto e HTML.
  • Geração de .eml para resposta.

Persistência

  • Configurações salvas em config.ini.
  • Carregamento automático ao abrir o formulário principal.
  • Persistência de:
    • SMTP
    • IMAP
    • POP3
    • OAuth2 endpoints
    • Client ID
    • Client Secret
    • Redirect URI
    • Scope
    • Segurança SSL/TLS

Arquitetura

flowchart TD
    A[TMainForm] --> B[TEmailService]
    A --> C[TConfigService]
    A --> D[TEmailReaderForm]

    B --> E[TOAuthService]
    B --> F[TIdSMTP]
    B --> G[Microsoft Graph API]

    D --> H[TEmailReaderService]
    H --> E
    H --> I[Microsoft Graph API]
    H --> J[TIdIMAP4]
    H --> K[TIdPOP3]

    C --> L[config.ini]
Loading

Unidades do Projeto

Unidade Responsabilidade
uMainForm Formulário principal. Permite configurar SMTP, OAuth2, segurança, mensagem, anexos, salvar/carregar configurações e disparar envio/leitura.
uEmailService Serviço de envio de e-mail via SMTP e Microsoft Graph API.
uConfigService Persistência das configurações em arquivo INI.
uOAuthTypes Tipos básicos de OAuth2: configurações, token e métodos.
uOAuthService Implementação dos fluxos OAuth2.
uEmailTypes Tipos de domínio para e-mail: mensagens, anexos, pastas, prioridades e flags.
uEmailReaderService Serviço de leitura de e-mails via Graph API, IMAP e POP3.
uEmailReaderForm Formulário de leitura, preview, listagem de pastas e geração de .eml.

Requisitos

Ambiente

  • Delphi com suporte a:
    • VCL
    • Generics
    • Anonymous methods
    • RTTI
    • System.JSON
    • System.NetEncoding
    • System.IOUtils

Recomenda-se Delphi 10.3 Rio ou superior.

Componentes / Bibliotecas

  • Indy 10.6.3.14 ou compatível.
  • Bibliotecas OpenSSL disponíveis para a aplicação.
  • Unidades Indy utilizadas:
    • IdSMTP
    • IdMessage
    • IdSSLOpenSSL
    • IdSASL
    • IdSASLPlain
    • IdSASLLogin
    • IdSASLOAuth
    • IdUserPassProvider
    • IdHTTP
    • IdHTTPServer
    • IdIMAP4
    • IdPOP3
    • IdCoderMIME
    • IdExplicitTLSClientServerBase

Serviços externos

Para OAuth2/Microsoft Graph:

  • Conta Microsoft 365 / Azure AD / Microsoft Entra ID.
  • Aplicativo registrado no Azure.
  • Permissões configuradas no Microsoft Graph ou Exchange Online.
  • Consentimento de administrador quando necessário.

Rede

Portas comuns usadas pelo projeto:

Serviço Porta
SMTP STARTTLS 587
SMTP SSL/TLS implícito 465
IMAP SSL/TLS 993
POP3 SSL/TLS 995
HTTPS Graph API 443
Listener local OAuth2 porta do Redirect URI, por exemplo 8080

Instalação

1. Obter o código

Clone o repositório ou baixe os arquivos-fonte.

git clone https://github.com/Matheus-Becker/DelphiMailOAuth.git

2. Abrir no Delphi

Este projeto é baseado em aplicação VCL.

Se o repositório não possuir .dproj, você pode:

  1. Criar um novo projeto VCL no Delphi.
  2. Adicionar as units:
    • uMainForm.pas
    • uEmailService.pas
    • uConfigService.pas
    • uOAuthService.pas
    • uOAuthTypes.pas
    • uEmailTypes.pas
    • uEmailReaderService.pas
    • uEmailReaderForm.pas
  3. Associar os formulários aos respectivos .dfm:
    • uMainForm.dfm
    • uEmailReaderForm.dfm
  4. Definir uMainForm como formulário principal.

3. Configurar OpenSSL

O Indy usa OpenSSL para SSL/TLS.

Para Windows, normalmente são necessários arquivos como:

OpenSSL 1.0.x:

libeay32.dll
ssleay32.dll

OpenSSL 1.1.x:

libcrypto-1_1-x64.dll
libssl-1_1-x64.dll

Coloque as DLLs:

  • na pasta do executável, ou
  • em uma pasta presente no PATH do sistema.

TLS 1.3 normalmente requer OpenSSL 1.1.1 ou superior, além de suporte adequado no Indy.


Configuração

A aplicação utiliza o arquivo config.ini, salvo na pasta do executável.

O caminho usado no código é:

ExtractFilePath(ParamStr(0)) + 'config.ini'

Exemplo de config.ini

[SMTP]
Host=smtp.office365.com
Port=587
User=usuario@dominio.com
Pass=senha_ou_app_password
FromEmail=usuario@dominio.com
FromName=Meu Sistema
ToEmail=destinatario@dominio.com
ToName=Destinatario
Security=1
SSLVersion=5

[OAuth]
AuthURL=https://login.microsoftonline.com/common/oauth2/v2.0/authorize
TokenURL=https://login.microsoftonline.com/common/oauth2/v2.0/token
DeviceURL=https://login.microsoftonline.com/common/oauth2/v2.0/devicecode
ClientId=00000000-0000-0000-0000-000000000000
ClientSecret=SEU_CLIENT_SECRET
RedirectURI=http://localhost:8080/
Scope=https://graph.microsoft.com/.default offline_access

[IMAP]
Host=outlook.office365.com
Port=993

[POP]
Host=outlook.office365.com
Port=995

⚠️ Importante: o arquivo config.ini pode conter segredos em texto puro.
Não versione esse arquivo em repositório público.


Mapeamento de Enumerados

Security

O campo Security do INI usa inteiro baseado em:

TSecurityType = (stSSL_TLS, stSTARTTLS);
Valor Significado
0 SSL/TLS implícito
1 STARTTLS

SSLVersion

O campo SSLVersion usa inteiro baseado em:

TSSLVersion = (
  svSSLv2,
  svSSLv23,
  svSSLv3,
  svTLSv1,
  svTLSv1_1,
  svTLSv1_2,
  svTLSv1_3
);
Valor Versão
0 SSLv2
1 SSLv23
2 SSLv3
3 TLSv1
4 TLSv1.1
5 TLSv1.2
6 TLSv1.3

Recomendação atual:

Security=1
SSLVersion=5

ou seja, STARTTLS com TLS 1.2.


Registro Microsoft / Azure OAuth2

Para usar OAuth2 com Microsoft Graph, SMTP/IMAP/POP3 OAuth ou Client Credentials, registre um aplicativo no Microsoft Entra ID.

1. Criar registro de aplicativo

  1. Acesse o portal do Azure.
  2. Vá em Microsoft Entra ID.
  3. Clique em App registrations.
  4. Clique em New registration.
  5. Informe um nome, por exemplo:
Delphi Email OAuth Client

2. Configurar Redirect URI

Para os fluxos interativos, configure uma Redirect URI local, por exemplo:

http://localhost:8080/

Essa URI deve ser a mesma usada no campo:

RedirectURI=http://localhost:8080/

O projeto sobe um listener local temporário na porta informada no Redirect URI.

3. Permissões Microsoft Graph

Para leitura e envio via Graph API, considere permissões como:

Delegadas

Permissão Uso
Mail.Read Ler e-mails
Mail.ReadWrite Ler e manipular e-mails
Mail.Send Enviar e-mail
User.Read Ler perfil básico
offline_access Obter refresh token

Aplicação / App-Only

Permissão Uso
Mail.Read Ler e-mails de qualquer caixa
Mail.ReadWrite Ler e alterar e-mails
Mail.Send Enviar e-mail como aplicação

Permissões de aplicação normalmente exigem admin consent.

4. SMTP/IMAP/POP3 OAuth

Para autenticação OAuth2 direta em protocolos de e-mail Microsoft 365, podem ser necessárias permissões como:

Recurso Escopo
IMAP https://outlook.office365.com/IMAP.AccessAsUser.All
POP https://outlook.office365.com/POP.AccessAsUser.All
SMTP https://outlook.office365.com/SMTP.Send

Exemplo de escopo combinado:

https://outlook.office365.com/SMTP.Send https://outlook.office365.com/IMAP.AccessAsUser.All offline_access

5. Endpoints comuns

Com tenant específico:

https://login.microsoftonline.com/seu-tenant-id/oauth2/v2.0/authorize
https://login.microsoftonline.com/seu-tenant-id/oauth2/v2.0/token
https://login.microsoftonline.com/seu-tenant-id/oauth2/v2.0/devicecode

Com common:

https://login.microsoftonline.com/common/oauth2/v2.0/authorize
https://login.microsoftonline.com/common/oauth2/v2.0/token
https://login.microsoftonline.com/common/oauth2/v2.0/devicecode

Fluxos OAuth2 Suportados

Método Enum Indicado para Observações
Tradicional omTraditional SMTP/IMAP/POP3 com usuário e senha Usa SASL PLAIN/LOGIN.
Authorization Code omAuthCode Aplicações desktop/web com usuário interagindo Abre navegador e captura código no listener local.
Authorization Code + PKCE omAuthCodePKCE Clientes públicos Recomendado quando não se deve usar client secret.
Device Code omDeviceCode Dispositivos sem browser fácil Mostra URL e código para o usuário.
Implicit omImplicit Legado Não recomendado para novos projetos.
ROPC omROPC Cenários muito específicos Não recomendado com MFA/políticas modernas.
Client Credentials omClientCredentials Daemon/App-Only No envio, o projeto desvia para Microsoft Graph API.
Refresh Token omRefreshToken Renovar token Requer armazenamento seguro do refresh token.

Envio de E-mail

O envio é feito pelo formulário principal.

Campos principais

Campo Descrição
E-mail remetente Endereço de origem
Nome remetente Nome exibido
Host SMTP Servidor SMTP
Porta SMTP Porta SMTP
Usuário Usuário de autenticação
Senha Senha ou segredo tradicional
Destinatário Para quem enviar
Método de autenticação Tradicional ou OAuth2
Security SSL/TLS ou STARTTLS
SSL Type Versão TLS/SSL
Assunto Assunto da mensagem
Content-Type Exemplo: text/plain; charset=utf-8
Corpo Texto da mensagem
Arquivos Anexos

Envio com autenticação tradicional

Fluxo:

  1. Selecione:
Tradicional (User/Pass)
  1. Configure:
    • Host SMTP
    • Porta
    • Usuário
    • Senha
    • Security
    • SSL Type
  2. Clique em ENVIAR E-MAIL.

O serviço configurará:

  • TIdSMTP
  • TIdSSLIOHandlerSocketOpenSSL
  • TIdUserPassProvider
  • TIdSASLPlain
  • TIdSASLLogin

Envio com OAuth2

Para OAuth2:

  1. Selecione o fluxo desejado.
  2. Configure endpoints OAuth:
    • Auth URL
    • Token URL
    • Device URL
    • Client ID
    • Client Secret
    • Redirect URI
    • Scope
  3. Clique em ENVIAR E-MAIL.
  4. Se o fluxo exigir interação, o navegador será aberto ou um código de dispositivo será exibido.

Para fluxos interativos, o projeto inicia um servidor HTTP local para receber o callback.


Envio via Microsoft Graph API

Quando o método selecionado é:

Client Credentials

o envio não continua pelo SMTP normal.

O projeto desvia para:

POST https://graph.microsoft.com/v1.0/users/{email}/sendMail

No modo delegado, o endpoint usado é:

POST https://graph.microsoft.com/v1.0/me/sendMail

No modo Client Credentials:

POST https://graph.microsoft.com/v1.0/users/{FromEmail}/sendMail

Exemplo simplificado do payload:

{
  "message": {
    "subject": "E-mail de teste",
    "body": {
      "contentType": "Text",
      "content": "Conteúdo do e-mail"
    },
    "from": {
      "emailAddress": {
        "address": "remetente@dominio.com",
        "name": "Sistema"
      }
    },
    "toRecipients": [
      {
        "emailAddress": {
          "address": "destinatario@dominio.com",
          "name": "Destinatário"
        }
      }
    ]
  },
  "saveToSentItems": "true"
}

Anexos no envio SMTP

Quando existem anexos marcados no TCheckListBox, o serviço:

  1. Muda o ContentType da mensagem para:
multipart/mixed; charset=utf-8
  1. Cria uma parte de texto com TIdText.
  2. Limpa o corpo principal da mensagem para evitar duplicidade.
  3. Adiciona anexos com TIdAttachmentFile.

Anexos na Graph API

Para anexos via Graph API, o serviço adiciona:

"attachments": [
  {
    "@odata.type": "#microsoft.graph.fileAttachment",
    "name": "documento.pdf",
    "contentType": "application/octet-stream",
    "contentBytes": "BASE64_AQUI"
  }
]

O arquivo é lido localmente e convertido para Base64.


Leitura de E-mail

A leitura é feita pelo formulário TEmailReaderForm.

Ele permite:

  • conectar;
  • atualizar;
  • escolher pasta;
  • escolher método;
  • listar pastas;
  • sobrescrever pasta;
  • visualizar e-mail;
  • gerar .eml de resposta.

Métodos de leitura

Método Enum Observações
Microsoft Graph API ermGraphAPI Recomendado para Microsoft 365
IMAP ermIMAP Suporta pastas e flags
POP3 ermPOP3 Mais simples, sem pastas e flags de servidor

Leitura via Graph API

Endpoint delegado:

GET https://graph.microsoft.com/v1.0/me/mailFolders/{folder}/messages?$top=50&$orderby=receivedDateTime desc&$expand=attachments

Endpoint App-Only:

GET https://graph.microsoft.com/v1.0/users/{email}/mailFolders/{folder}/messages?$top=50&$orderby=receivedDateTime desc&$expand=attachments

Exemplos de pastas:

Pasta Nome comum Graph
Caixa de entrada inbox
Itens enviados sentitems
Rascunhos drafts
Lixeira deleteditems
Arquivo archive
Junk/Spam junkemail

Se a pasta padrão não funcionar, use Listar Pastas ou preencha o campo Usar com o identificador correto.


Leitura via IMAP

A leitura IMAP usa TIdIMAP4.

Recursos:

  • seleção de mailbox;
  • listagem de mailboxes;
  • leitura de flags;
  • anexos;
  • corpo texto/HTML;
  • suporte a SASL;
  • suporte a XOAUTH2.

Pastas padrão no código:

Pasta Nome usado
Inbox INBOX
Sent INBOX.Sent
Drafts INBOX.Drafts
Trash INBOX.Trash
Archive INBOX.Archive
Outbox Outbox
Spam INBOX.spam
Junk INBOX.Junk

Servidores diferentes podem usar nomes diferentes.
Use Listar Pastas para descobrir os nomes reais.


Leitura via POP3

POP3 é mais limitado.

Limitações conhecidas:

  • não trabalha com múltiplas pastas;
  • não mantém flags de servidor como:
    • lida;
    • sinalizada;
    • respondida;
    • rascunho.

No código, mensagens POP3 são tratadas como:

IsRead := True;
IsFlagged := False;
IsAnswered := False;
IsDraft := False;

Listar pastas

O formulário possui botão Listar Pastas.

Para Graph:

GET https://graph.microsoft.com/v1.0/me/mailFolders

ou:

GET https://graph.microsoft.com/v1.0/users/{email}/mailFolders

Para IMAP:

LIMAP.ListMailBoxes(Result)

Preview de mensagem

Ao selecionar um e-mail, o preview exibe:

  • De
  • Enviado por
  • Para
  • CC
  • BCC
  • Responder para
  • Data
  • Message-ID
  • Status
  • Assunto
  • Corpo
  • Anexos
  • Anexos inline

Geração de Arquivo .eml

Ao dar duplo clique em um e-mail, o projeto gera um arquivo .eml de resposta.

O arquivo é salvo em pasta temporária com nome parecido com:

reply_{id}_{timestamp}.eml

Depois disso, o arquivo é aberto com ShellExecute, acionando o cliente de e-mail padrão do Windows.


Recursos do .eml

O método BuildEmlContent suporta:

  • cabeçalhos RFC 822;
  • From;
  • To;
  • Cc;
  • Bcc;
  • Subject;
  • Date;
  • Message-ID;
  • In-Reply-To;
  • References;
  • prioridade;
  • organização;
  • confirmação de leitura;
  • multipart/mixed;
  • multipart/related;
  • multipart/alternative;
  • texto puro;
  • HTML;
  • anexos Base64;
  • imagens inline;
  • citação da mensagem original em respostas.

Exemplo de cabeçalhos de threading:

In-Reply-To: <mensagem-original@dominio>
References: <mensagem-original@dominio>

Isso ajuda clientes de e-mail a agrupar a conversa corretamente.


Uso Programático

Carregar configuração e enviar e-mail

uses
  uConfigService, uEmailService, uEmailTypes;

var
  AppConfig: TAppConfig;
  EmailService: TEmailService;
  Mensagem: TMensagem;
begin
  TConfigService.LoadFromFile('config.ini', AppConfig);

  AppConfig.EmailConfig.OAuthMethod := omTraditional;

  Mensagem.Subject := 'Teste';
  Mensagem.ContentType := 'text/plain; charset=utf-8';
  Mensagem.Body := 'Mensagem de teste.';
  SetLength(Mensagem.Attachments, 0);

  EmailService := TEmailService.Create(nil);
  try
    if EmailService.SendEmail(AppConfig.EmailConfig, Mensagem) then
      ShowMessage('E-mail enviado com sucesso!')
    else
      ShowMessage('Falha no envio.');
  finally
    EmailService.Free;
  end;
end;

Ler e-mails via Graph API

uses
  uEmailReaderService, uEmailTypes;

var
  ReaderService: TEmailReaderService;
  Emails: TEmailList;
begin
  ReaderService := TEmailReaderService.Create;
  try
    if ReaderService.Authenticate(AppConfig.EmailConfig) then
    begin
      Emails := ReaderService.ReadEmails(
        AppConfig.EmailConfig,
        efInbox,
        50,
        ermGraphAPI
      );
    end;
  finally
    ReaderService.Free;
  end;
end;

Ler e-mails via IMAP

Emails := ReaderService.ReadEmails(
  AppConfig.EmailConfig,
  efInbox,
  50,
  ermIMAP
);

Ler e-mails via POP3

Emails := ReaderService.ReadEmails(
  AppConfig.EmailConfig,
  efInbox,
  50,
  ermPOP3
);

Logs e Diagnóstico

A aplicação registra logs em tela e também em arquivos de apoio.

Logs em tela

Os principais formulários possuem áreas de log:

  • mmoLog no formulário principal.
  • StatusBar no formulário de leitura.

Arquivos gerados

Dependendo da operação, podem ser gerados os arquivos abaixo na pasta do executável:

Arquivo Conteúdo
smtp_debug.txt Log de comunicação SMTP
LSMTP_JSON.json Snapshot JSON de objetos SMTP
IDHTTP_JSON.json Snapshot JSON de objetos HTTP
oauth_curl_log.txt Log de requisições OAuth em formato parecido com cURL
oauth_curl_get_log.txt Log de requisições GET
token_response_log.txt Resposta bruta do endpoint de token
GRAPH_API_READ.json Resposta da leitura Graph API
LHTTPGET_JSON.json Snapshot JSON do cliente HTTP

Exemplo de log cURL

O serviço OAuth monta logs no estilo:

curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token"
  -H "Content-Type: application/x-www-form-urlencoded"
  -H "UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
  -d "grant_type=authorization_code"
  -d "code=XXXX"

Isso ajuda a reproduzir a requisição em ferramentas como:

  • Postman
  • Insomnia
  • curl
  • PowerShell

Estrutura de Dados

TAppConfig

TAppConfig = record
  EmailConfig: TEmailConfig;
end;

TEmailConfig

Contém configurações principais de e-mail e OAuth.

Campos:

FromEmail: string;
FromName: string;
SMTPHost: string;
SMTPPort: Integer;
SMTPUser: string;
SMTPPass: string;
ToEmail: string;
ToName: string;
IMAPHost: string;
IMAPPort: Integer;
POPHost: string;
POPPort: Integer;
SecurityType: TSecurityType;
SSLVersion: TSSLVersion;
OAuthConfig: TOAuthConfig;
OAuthMethod: TOAuthMethod;

TMensagem

TMensagem = record
  Subject: String;
  ContentType: String;
  Body: String;
  Attachments: TArray<string>;
end;

TOAuthConfig

TOAuthConfig = record
  ClientId: string;
  ClientSecret: string;
  RedirectUri: string;
  AuthEndpoint: string;
  TokenEndpoint: string;
  DeviceEndpoint: string;
  Scope: string;
  Username: string;
  Password: string;
end;

TOAuthToken

TOAuthToken = record
  AccessToken: string;
  RefreshToken: string;
  ExpiresIn: Integer;
  ExpiresAt: TDateTime;
  TokenType: string;
  function IsValid: Boolean;
end;

TEmailMessage

Representa uma mensagem de e-mail lida ou processada.

Principais campos:

Id: string;
MessageId: string;
Subject: string;
FromName: string;
FromEmail: string;
SenderEmail: string;
ToList: TArray<string>;
CcList: TArray<string>;
BccList: TArray<string>;
ReplyToList: TArray<string>;
ReceivedAt: TDateTime;
SentAt: TDateTime;
BodyText: string;
BodyHTML: string;
IsRead: Boolean;
IsFlagged: Boolean;
IsAnswered: Boolean;
IsDraft: Boolean;
HasAttachments: Boolean;
Priority: TEmailPriority;
Attachments: TArray<TEmailAttachment>;

TEmailAttachment

TEmailAttachment = record
  Name: string;
  FileName: string;
  ContentType: string;
  Size: Integer;
  ContentBytes: TBytes;
  IsInline: Boolean;
  ContentID: string;
  ContentLocation: string;
  ContentDescription: string;
  CharSet: string;
  function IsImage: Boolean;
end;

Segurança

⚠️ Segredos em texto puro

O arquivo config.ini pode conter:

  • senha SMTP;
  • client secret;
  • tokens em logs;
  • respostas OAuth completas.

Não faça commit de:

config.ini
*.log
smtp_debug.txt
oauth_curl_log.txt
token_response_log.txt
GRAPH_API_READ.json

Tokens em logs

O código atual pode registrar informações sensíveis em logs, por exemplo:

  • access token;
  • resposta do endpoint de token;
  • headers de autorização em logs cURL.

Para produção:

  • remova logs de token;
  • mascare tokens;
  • não grave respostas brutas de token em disco;
  • use logs apenas em ambiente de desenvolvimento.

Boas práticas recomendadas

  • Use TLS 1.2 ou superior.
  • Evite SSLv2, SSLv3 e TLS antigo.
  • Não use Implicit para novos projetos.
  • Evite ROPC sempre que possível.
  • Prefira Authorization Code + PKCE para aplicações desktop.
  • Use Client Credentials apenas para daemons/APIs.
  • Armazene refresh tokens com criptografia.
  • Considere usar DPAPI, Windows Credential Manager ou cofre de segredos.
  • Não mantenha ClientSecret em repositório público.

Sugestão de .gitignore

Adicione no seu repositório:

# Configurações locais
config.ini

# Logs e arquivos de diagnóstico
*.log
smtp_debug.txt
oauth_curl_log.txt
oauth_curl_get_log.txt
token_response_log.txt
GRAPH_API_READ.json
LSMTP_JSON.json
IDHTTP_JSON.json
LHTTPGET_JSON.json

# Delphi
__history/
__recovery/
*.dcu
*.local
*.identcache
*.dproj.local
*.stat

# Binários
*.exe
*.dll

Solução de Problemas

DLL OpenSSL não encontrada

Erro típico:

Could not load SSL library

Causa:

  • DLLs ausentes;
  • DLLs 32/64 bits incompatíveis;
  • versão OpenSSL incompatível.

Solução:

  • coloque as DLLs corretas na pasta do executável;
  • confirme se a aplicação é 32 ou 64 bits;
  • use OpenSSL compatível com o Indy.

Falha de handshake TLS

Possíveis causas:

  • servidor exige TLS 1.2;
  • SSLVersion incorreto;
  • Security incorreto;
  • firewall/proxy bloqueando.

Solução:

Security=1
SSLVersion=5

Erro de autenticação SMTP

Exemplo:

535 5.7.3 Authentication unsuccessful

Possíveis causas:

  • autenticação básica desabilitada;
  • usuário/senha inválidos;
  • MFA exigindo OAuth;
  • escopo OAuth incorreto;
  • SMTP AUTH não habilitado no mailbox.

Solução:

  • use OAuth2;
  • verifique permissões;
  • verifique se SMTP está habilitado no usuário/caixa.

Erro 401 na Graph API

Causa:

  • token expirado;
  • tenant incorreto;
  • escopo incorreto;
  • consentimento ausente.

Solução:

  • obtenha novo token;
  • valide AuthURL e TokenURL;
  • confira permissões no Azure.

Erro 403 na Graph API

Causa:

  • permissão insuficiente;
  • permissão de aplicação sem admin consent;
  • usuário sem licença ou sem acesso.

Solução:

  • conceda consentimento de administrador;
  • confira permissões Mail.Read, Mail.ReadWrite, Mail.Send;
  • confirme se o e-mail informado existe no modo App-Only.

Erro 404 na Graph API

Causa:

  • e-mail inexistente;
  • pasta inexistente;
  • endpoint App-Only usando e-mail errado.

Solução:

  • confira FromEmail;
  • use Listar Pastas;
  • use o campo Usar para informar a pasta correta.

Porta local já em uso

Erro ao subir listener OAuth:

Port 8080 already in use

Solução:

  • feche a aplicação anterior;
  • altere RedirectURI para outra porta:
RedirectURI=http://localhost:8081/

Device Code não conclui

Sintoma:

authorization_pending

Isso significa que o usuário ainda não concluiu a autenticação.

Solução:

  • abra a URL exibida;
  • digite o código;
  • conclua login e consentimento.

POP3 não mostra flags

Comportamento esperado.

POP3 não suporta flags como IMAP.

Se precisar de:

  • lida/não lida;
  • pasta;
  • sinalização;
  • rascunho;

use:

  • Graph API;
  • IMAP.

E-mail com caracteres estranhos

Pode acontecer ao ler mensagens com charset diferente.

O projeto contém helper:

FixIndyCharset(...)

Ele tenta corrigir casos comuns como:

  • ISO-8859-1
  • Windows-1252

Anexos grandes

Anexos muito grandes podem causar lentidão ou estouro de memória, principalmente porque o projeto carrega bytes em memória.

Recomendações:

  • limite o tamanho de anexos;
  • evite carregar muitos anexos simultaneamente;
  • para produção, prefira stream/disco quando possível.

Roadmap

Melhorias sugeridas:

  • Persistir OAuthMethod no config.ini.
  • Persistir refresh token com criptografia.
  • Remover ou mascarar tokens dos logs.
  • Suporte completo a TLS 1.3.
  • Preview HTML com TEdgeBrowser.
  • Download de anexos para disco.
  • Marcar como lido via Graph API.
  • Excluir e-mail via Graph API.
  • Envio em lote via $batch.
  • Testes unitários.
  • Suporte a proxy.
  • Uso de thread separada para envio/leitura.
  • Armazenamento seguro de credenciais com DPAPI ou Credential Manager.

Contribuição

  1. Faça um fork do projeto.
  2. Crie uma branch:
git checkout -b feature/minha-melhoria
  1. Commit suas alterações:
git commit -m "feat: adiciona suporte a XYZ"
  1. Envie para o remoto:
git push origin feature/minha-melhoria
  1. Abra um Pull Request.

Licença

Este projeto está disponível sob licença de sua escolha.

About

Aplicação Delphi para envio e leitura de e-mails com Indy, OAuth2, SMTP, IMAP, POP3, SSL/TLS, STARTTLS, Microsoft Graph API anexos e geração de arquivos .eml. Requer DLLs OpenSSL na pasta do executável.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages