feat: replace maildev with mailpit #64
3 changed files with 88 additions and 28 deletions
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue