feat: replace maildev with mailpit #64

Merged
realaravinth merged 2 commits from fix-maildev into master 2024-07-23 14:46:33 +05:30
3 changed files with 88 additions and 28 deletions

View file

@ -69,18 +69,22 @@ steps:
# secrets: [RELEASE_BOT_GPG_SIGNING_KEY, DUMBSERVE_PASSWORD, GPG_PASSWORD]
#
services:
email:
image: axllent/mailpit
environment:
- MP_SMTP_AUTH=admin:password
- MP_MAX_MESSAGES=5000
- MP_SMTP_AUTH_ALLOW_INSECURE=1
- MP_SMTP_BIND_ADDR=0.0.0.0:10025
- MP_SMTP_AUTH_ALLOW_INSECURE=true
- MP_UI_BIND_ADDR=0.0.0.0:1080
database:
image: postgres
environment:
- POSTGRES_PASSWORD=password
email:
image: maildev/maildev:latest
environment:
- MAILDEV_SMTP_PORT=10025
- MAILDEV_INCOMING_USER=admin
- MAILDEV_INCOMING_PASS=password
meilisearch:
image: getmeili/meilisearch:v1.9
environment:

View file

@ -2,14 +2,17 @@ version: "3"
services:
email:
image: maildev/maildev:latest
restart: always
container_name: vanigam-dash-maildev
network_mode: host
image: axllent/mailpit
ports:
- 1080:1080
- 10025:10025
environment:
- MAILDEV_SMTP_PORT=10025
- MAILDEV_INCOMING_USER=admin
- MAILDEV_INCOMING_PASS=password
- MP_SMTP_AUTH=admin:password
- MP_MAX_MESSAGES=5000
- MP_SMTP_AUTH_ALLOW_INSECURE=1
- MP_SMTP_BIND_ADDR=0.0.0.0:10025
- MP_SMTP_AUTH_ALLOW_INSECURE=true
- MP_UI_BIND_ADDR=0.0.0.0:1080
postgres:
image: postgres:16.3

View file

@ -15,6 +15,7 @@ impl AccountValidationLinkOutMailerPort for LettreMailer {
first_name: &str,
validation_secret: &str,
) -> OutMailerPortResult<()> {
// TODO: generate link from validation secret
let email = Message::builder()
.from(self.from.parse().unwrap())
.reply_to(self.reply_to.parse().unwrap())
@ -40,21 +41,63 @@ mod tests {
use reqwest::Client;
use url::Url;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
//#[derive(Deserialize, Clone)]
//struct MaildevAddress {
// address: String,
// name: String,
//}
//#[derive(Deserialize, Clone)]
//struct MaildevEmail {
// id: String,
// from: Vec<MaildevAddress>,
// to: Vec<MaildevAddress>,
// subject: String,
// text: String,
// html: Option<String>,
//}
#[derive(Deserialize, Clone)]
struct MaildevAddress {
struct MailPitAddress {
#[serde(rename = "Address")]
address: String,
#[serde(rename = "Name")]
name: String,
}
#[derive(Deserialize, Clone)]
struct MaildevEmail {
pub struct MailpitSummary {
#[serde(rename = "ID")]
id: String,
from: Vec<MaildevAddress>,
to: Vec<MaildevAddress>,
#[serde(rename = "To")]
to: Vec<MailPitAddress>,
}
#[derive(Deserialize, Clone)]
pub struct MailpitEmail {
#[serde(rename = "From")]
from: MailPitAddress,
#[serde(rename = "To")]
to: Vec<MailPitAddress>,
#[serde(rename = "ReplyTo")]
reply_to: Vec<MailPitAddress>,
#[serde(rename = "Subject")]
subject: String,
#[serde(rename = "Text")]
text: String,
html: Option<String>,
#[serde(rename = "HTML")]
html: String,
}
#[derive(Deserialize, Clone)]
pub struct MailpitListEmails {
messages: Vec<MailpitSummary>,
}
#[derive(Serialize, Clone)]
pub struct MailpitDeleteEmail {
IDs: Vec<String>,
}
#[actix_rt::test]
@ -77,21 +120,31 @@ mod tests {
let mut u = Url::parse(&maildev_url).unwrap();
u.set_path("/email");
let maildev_emails: Vec<MaildevEmail> =
u.set_path("/api/v1/messages");
let mailpit_emails: MailpitListEmails =
c.get(u.clone()).send().await.unwrap().json().await.unwrap();
let maildev_email = maildev_emails
let mailpit_summary = mailpit_emails
.messages
.iter()
.find(|e| e.to.iter().any(|f| f.address == email))
.unwrap();
assert!(maildev_email.text.contains(validation_secret));
assert!(maildev_email.text.contains(username));
assert!(maildev_email
u.set_path(&format!("/api/v1/message/{}", mailpit_summary.id));
let mailpit_email: MailpitEmail =
c.get(u.clone()).send().await.unwrap().json().await.unwrap();
assert!(mailpit_email.text.contains(validation_secret));
assert!(mailpit_email.text.contains(username));
assert!(mailpit_email
.to
.iter()
.any(|t| t.address == email && t.name == username));
u.set_path(&format!("/email/{}", maildev_email.id));
c.delete(u).send().await.unwrap();
u.set_path("/api/v1/messages");
let payload = MailpitDeleteEmail {
IDs: vec![mailpit_summary.id.clone()],
};
c.delete(u).json(&payload).send().await.unwrap();
}
}