Passer au contenu principal

MailHog vs Mailpit : Test des e-mails de vérification et de réinitialisation de mot de passe avec Casdoor

· Lecture de 10 minutes
Yang Luo
Casdoor Maintainer

MailHog et Mailpit sont tous deux de faux serveurs SMTP pour le développement : ils acceptent chaque message, le conservent et l'affichent dans une interface web au lieu de le livrer. Les deux utilisent les mêmes ports par défaut, SMTP sur 1025 et l'interface web et l'API sur 8025, donc l'adresse SMTP est smtp://127.0.0.1:1025 et la boîte de réception est à http://127.0.0.1:8025 pour l'un ou l'autre. La différence réside dans la maintenance : la dernière version de MailHog, v1.0.1, est sortie en août 2020, tandis que Mailpit a publié la v1.33.0 le 31 octobre 2026. Pour un nouveau projet, utilisez Mailpit. Casdoor envoie aux deux via un fournisseur SMTP simple, vous pouvez donc tester les codes d'inscription, les e-mails de réinitialisation de mot de passe et les liens magiques sans un vrai compte de messagerie.

MailHog vs Mailpit en un coup d'œil​

MailHogMailpit
Dernière versionv1.0.1, 2020-08-11v1.33.0, 2026-10-31
Dernier commit sur la branche par défaut2022-08-022026-10-31
LicenseMITMIT
Default SMTP port10251025
Default web UI and API port80258025
Docker imagemailhog/mailhog, amd64 onlyaxllent/mailpit, amd64, arm64 and 386
HTTP APIv1 and v2: list, get, delete, search by from, to or containingv1: list, get, delete, search with filters such as to: and subject:, latest message shortcut
Default storageIn memoryTemporary SQLite database, deleted on exit
Persistent storageMongoDB or MaildirSQLite file (MP_DATABASE) or rqlite
Message limitNone documentedKeeps the newest 500 by default (MP_MAX_MESSAGES)
HTML check, link check, spam checkNoYes
Webhook on new mailNoYes (MP_WEBHOOK_URL)
SMTP TLSNot offeredOptional STARTTLS or SSL/TLS
Failure injectionJimChaos
Release a message to a real SMTP serverYesYes
POP3 serverNoYes, optional
Basic auth for the web UIYesYes

Les statistiques de Docker Hub montrent que beaucoup de personnes téléchargent encore MailHog. Cela reflète les anciens tutoriels et fichiers CI, pas une activité réelle : un ticket ouvert sur le dépôt MailHog intitulé "THIS PROJECT IS DEAD!" contient une réponse de l'auteur en 2023 indiquant qu'il n'a plus le temps de maintenir le projet. Le README de Mailpit se décrit comme inspiré par MailHog et pointe vers ce même commentaire.

L'architecture de l'image est plus importante qu'elle ne le paraît. Sur un ordinateur portable Apple Silicon ou un runner CI ARM, mailhog/mailhog fonctionne uniquement en émulation, tandis que axllent/mailpit dispose d'une image native arm64.

Exécutez l'un ou l'autre avec Docker​

MailHog:

docker run -d --name mailhog -p 1025:1025 -p 8025:8025 mailhog/mailhog

Mailpit:

docker run -d --name mailpit -p 1025:1025 -p 8025:8025 axllent/mailpit

Mailpit conserve les e-mails dans une base de données temporaire qui disparaît lorsque le conteneur s'arrête. Pour la conserver entre les redémarrages, montez un volume et définissez MP_DATABASE:

docker run -d --name mailpit \
-v "$PWD/mailpit-data:/data" \
-e MP_DATABASE=/data/mailpit.db \
-p 1025:1025 -p 8025:8025 \
axllent/mailpit

Sans Docker, brew install mailhog et brew install mailpit fonctionnent tous deux sous macOS, et Mailpit fournit des binaires statiques pour Windows, Linux et macOS sur sa page de versions.

Dans GitHub Actions, exécutez-le comme conteneur de service à côté de votre job de test:

services:
mailpit:
image: axllent/mailpit
ports:
- 1025:1025
- 8025:8025

Configurer Casdoor avec MailHog ou Mailpit​

Casdoor ne possède pas de type de fournisseur distinct pour MailHog ou Mailpit, et il n'en a pas besoin. Le type d'e-mail Default envoie via SMTP, et ces deux outils sont des serveurs SMTP.

  1. En tant qu'administrateur global, ajoutez un fournisseur dans l'organisation admin ou built-in.
  2. Définissez Category sur Email et Type sur Default.
  3. Définissez Host sur l'endroit où l'outil s'exécute et Port sur 1025.
  4. Laissez Username et Password vides.
  5. Cliquez sur Test SMTP Connection, puis sur Send Testing Email, et vérifiez l'interface web sur le port 8025.

Les pages étape par étape avec captures d'écran sont Test email with MailHog et Test email with Mailpit.

Quelques détails déterminent si cela fonctionne du premier coup:

Laissez le mode SSL sur Auto, ou définissez-le sur Disable. Dans le mode Auto, Casdoor utilise le TLS implicite uniquement sur le port 465 et effectue une mise à niveau avec STARTTLS uniquement si le serveur le propose. Ni MailHog ni Mailpit par défaut ne proposent STARTTLS sur le port 1025, donc la connexion reste en clair. Ne choisissez pas Enable : cela force le TLS implicite, et la poignée de main échoue contre un serveur en texte brut. Le tableau des modes SSL détaille le comportement complet.

Laissez les identifiants vides. Casdoor se connecte au serveur SMTP uniquement lorsque Username est défini. Si vous le remplissez, l'authentification PLAIN de Go refuse d'envoyer le mot de passe sur une connexion non chiffrée sauf si l'hôte est localhost, ce qui fait qu'un MailHog situé sur 192.168.x.x échoue avec une erreur d'authentification bien que MailHog accepte n'importe quel login. Mailpit par défaut ne demande aucune authentification.

Utilisez le bon hôte. 127.0.0.1 fonctionne uniquement lorsque Casdoor et le collecteur d'e-mails tournent sur la même machine. Si les deux tournent dans Docker Compose, utilisez le nom du service, tel que mailpit, comme hôte.

Utilisez un fournisseur global. Un fournisseur appartenant à une organisation ordinaire ne peut atteindre que des adresses Internet, il ne peut donc pas se connecter à 127.0.0.1 ou à une IP privée. Les fournisseurs dans admin ou built-in ne sont pas restreints. Voir Quelles adresses un fournisseur peut-il atteindre.

Définissez origin pour les liens. Les codes de vérification fonctionnent immédiatement. Les liens de réinitialisation de mot de passe et les liens magiques nécessitent que Casdoor connaisse son URL publique, via origin dans conf/app.conf ou une requête sur un hôte loopback. Sinon, le lien de réinitialisation est omis de l'e-mail et les liens magiques échouent. Voir Modèles.

Enfin, ajoutez le fournisseur à votre application dans Add providers to an application afin que l'inscription et la réinitialisation de mot de passe l'utilisent réellement.

Lire le code de vérification dans un test automatisé​

Les codes de vérification de Casdoor comportent six chiffres, et le modèle par défaut indique "Here is your code: " suivi du code. Un test de bout en bout inscrit un utilisateur, demande à Casdoor d'envoyer le code, puis le lit depuis l'API du collecteur d'e-mails.

Avec Mailpit, recherchez par destinataire et ouvrez la correspondance la plus récente. GET /api/v1/search renvoie les correspondances de la plus récente à la plus ancienne, et GET /api/v1/message/{ID} renvoie les corps Text et HTML analysés:

import { request } from "@playwright/test";

const MAILPIT = process.env.MAILPIT_URL ?? "http://127.0.0.1:8025";

export async function latestCode(to: string): Promise<string> {
const api = await request.newContext({ baseURL: MAILPIT });
for (let i = 0; i < 20; i++) {
const res = await api.get("/api/v1/search", {
params: { query: `to:"${to}"`, limit: "1" },
});
const { messages } = await res.json();
if (messages.length > 0) {
const msg = await (await api.get(`/api/v1/message/${messages[0].ID}`)).json();
const match = (msg.Text || msg.HTML).match(/code: (\d{6})/);
if (match) return match[1];
}
await new Promise((r) => setTimeout(r, 500));
}
throw new Error(`no verification email for ${to}`);
}

Si un seul test envoie des e-mails à la fois, GET /api/v1/message/latest ignore l'étape de recherche. Avant chaque test, DELETE /api/v1/messages sans corps vide la boîte de réception.

Avec MailHog, l'appel le plus proche est GET /api/v2/search?kind=to&query=<address>. Les messages sont renvoyés du plus récent au plus ancien dans items, et le corps se trouve dans items[0].Content.Body :

const res = await api.get("/api/v2/search", {
params: { kind: "to", query: to, limit: "1" },
});
const { items } = await res.json();
const body: string = items[0]?.Content.Body ?? "";

Content.Body est le corps MIME brut. Casdoor utilise l'encodage quoted-printable, donc = devient =3D et les lignes longues sont coupées par des sauts de ligne souples terminés par =. Décodez-le d'abord, ou gardez le code près du début d'un modèle court. Videz MailHog avec DELETE /api/v1/messages.

Migration de MailHog vers Mailpit​

Comme les ports correspondent, la plupart des migrations nécessitent une modification d'une seule ligne dans docker-compose.yml : remplacez mailhog/mailhog par axllent/mailpit. Le fournisseur de Casdoor conserve le même hôte et le même port. Ce qui change :

  • Paramètres. MailHog lit les variables MH_* ; Mailpit lit les variables MP_*. Si vous utilisiez MH_STORAGE=maildir ou MongoDB, passez à MP_DATABASE.
  • Helpers de test. Mailpit n'a pas d'endpoints /api/v2. Réécrivez les appels à /api/v2/messages et /api/v2/search pour utiliser /api/v1/messages et /api/v1/search, et lisez messages[].ID ainsi que Text ou HTML au lieu de items[].Content.Body. Le décodage quoted-printable disparaît.
  • Syntaxe de recherche. kind=to&query=a@example.com devient query=to:"a@example.com".
  • Injection de pannes. Jim n'a pas de drapeaux (flags) dans Mailpit ; utilisez Chaos.
  • Authentification. Si une application exige une connexion via SMTP en clair, démarrez Mailpit avec MP_SMTP_AUTH_ACCEPT_ANY=1 et MP_SMTP_AUTH_ALLOW_INSECURE=1. Pour Casdoor, il est plus simple de laisser les identifiants vides.
  • Rétention. Par défaut, Mailpit ne conserve que les 500 messages les plus récents. Augmentez MP_MAX_MESSAGES si une longue série de tests nécessite davantage de stockage.

Passage en production​

MailHog et Mailpit ne livrent jamais d'e-mails aux vraies boîtes de réception sauf si vous libérez manuellement les messages, la production nécessite donc un vrai fournisseur. Dans Casdoor, vous échangez le fournisseur, pas les modèles. Les modèles d'e-mail, le placeholder de code %s et le bloc <reset-link> restent identiques :

Une configuration courante consiste à garder Mailpit en développement et CI, et le vrai fournisseur en production. Chaque environnement pointe son application vers un fournisseur différent, afin que le flux d'inscription que vous testez soit celui qui sera déployé.

Références​