diff --git a/.woodpecker.yml b/.woodpecker.yml index 3fe477e..0243fa8 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -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: diff --git a/docker-compose-dev-deps.yml b/docker-compose-dev-deps.yml index 4d7f817..ae09c28 100644 --- a/docker-compose-dev-deps.yml +++ b/docker-compose-dev-deps.yml @@ -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 diff --git a/src/identity/adapters/output/mailer/lettre/account_validation_link.rs b/src/identity/adapters/output/mailer/lettre/account_validation_link.rs index e926c04..058c73b 100644 --- a/src/identity/adapters/output/mailer/lettre/account_validation_link.rs +++ b/src/identity/adapters/output/mailer/lettre/account_validation_link.rs @@ -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, + // to: Vec, + // subject: String, + // text: String, + // html: Option, + //} #[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, - to: Vec, + #[serde(rename = "To")] + to: Vec, + } + + #[derive(Deserialize, Clone)] + pub struct MailpitEmail { + #[serde(rename = "From")] + from: MailPitAddress, + #[serde(rename = "To")] + to: Vec, + #[serde(rename = "ReplyTo")] + reply_to: Vec, + #[serde(rename = "Subject")] subject: String, + #[serde(rename = "Text")] text: String, - html: Option, + #[serde(rename = "HTML")] + html: String, + } + + #[derive(Deserialize, Clone)] + pub struct MailpitListEmails { + messages: Vec, + } + + #[derive(Serialize, Clone)] + pub struct MailpitDeleteEmail { + IDs: Vec, } #[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 = + 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(); } }