1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

WIP: email sending crate

This commit is contained in:
Quentin Gliech
2022-01-19 12:10:03 +01:00
parent 29b2fc2e43
commit 2e12f43c0e
7 changed files with 259 additions and 5 deletions

18
crates/email/Cargo.toml Normal file
View File

@ -0,0 +1,18 @@
[package]
name = "mas-email"
version = "0.1.0"
authors = ["Quentin Gliech <quenting@element.io>"]
edition = "2021"
license = "Apache-2.0"
[dependencies]
tokio = { version = "1.15.0", features = ["macros"] }
mas-templates = { path = "../templates" }
anyhow = "1.0.52"
async-trait = "0.1.52"
[dependencies.lettre]
version = "0.10.0-rc.4"
default-features = false
features = ["tokio1-rustls-tls", "hostname", "builder", "tracing", "pool"]

78
crates/email/src/lib.rs Normal file
View File

@ -0,0 +1,78 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use lettre::{
message::{Mailbox, MessageBuilder, MultiPart},
AsyncTransport, Message,
};
use mas_templates::{EmailVerificationContext, Templates};
pub struct Mailer {
templates: Templates,
from: Mailbox,
reply_to: Mailbox,
}
impl Mailer {
pub fn new<T>(templates: &Templates, from: Mailbox, reply_to: Mailbox) -> Self {
Self {
templates: templates.clone(),
from,
reply_to,
}
}
fn base_message(&self) -> MessageBuilder {
Message::builder()
.from(self.from.clone())
.reply_to(self.reply_to.clone())
}
async fn prepare_verification_email(
&self,
to: Mailbox,
context: &EmailVerificationContext,
) -> anyhow::Result<Message> {
let plain = self
.templates
.render_email_verification_txt(context)
.await?;
let html = self
.templates
.render_email_verification_html(context)
.await?;
let multipart = MultiPart::alternative_plain_html(plain, html);
let message = self.base_message().to(to).multipart(multipart)?;
Ok(message)
}
pub async fn send_verification_email<T>(
&self,
transport: &T,
to: Mailbox,
context: &EmailVerificationContext,
) -> anyhow::Result<()>
where
T: AsyncTransport + Send + Sync,
T::Error: std::error::Error + Send + Sync + 'static,
{
let message = self.prepare_verification_email(to, context).await?;
transport.send(message).await?;
Ok(())
}
}