Email admins on new account registration

This commit is contained in:
Chris Jean-Marie 2024-10-31 19:17:06 +00:00
parent d9d3834e8b
commit 6417a0445c
4 changed files with 45 additions and 37 deletions

View File

@ -1,6 +1,6 @@
use dotenvy::var;
use lettre::{
message::{header::ContentType, Mailbox},
message::{header::{ContentType, HeaderName, HeaderValue},Mailbox},
transport::smtp::authentication::Credentials,
Message, SmtpTransport, Transport,
};
@ -8,7 +8,7 @@ use lettre::{
fn create_mailer() -> SmtpTransport {
// Get the server settings from the env file
let smtp_server_name = var("SMTP_SERVER_NAME").expect("SMTP_SERVER_NAME not set");
let smtp_server_port = var("SMTP_SERVER_PORT").expect("SMTP_SERVER_PORT not set");
//let smtp_server_port = var("SMTP_SERVER_PORT").expect("SMTP_SERVER_PORT not set");
// Get the username and password from the env file
let username = var("EMAIL_USERNAME").expect("EMAIL_USERNAME not set");
@ -26,20 +26,26 @@ fn create_mailer() -> SmtpTransport {
.build()
}
pub fn send_email(subject: String, recipient: String, body: String) {
pub fn send_emails(subject: String, recipients: String, body: String) {
let username = var("EMAIL_USERNAME").expect("EMAIL_USERNAME not set");
// Build the email
let email = Message::builder()
let mut email = Message::builder()
.from(username.parse::<Mailbox>().unwrap())
.to(recipient.parse::<Mailbox>().unwrap())
.to(username.parse::<Mailbox>().unwrap())
.subject(subject)
.header(ContentType::TEXT_HTML)
.body(body.to_string())
.body(body)
.unwrap();
let headers = email.headers_mut();
//headers.set(To(recipients));
headers.insert_raw(HeaderValue::new(HeaderName::new_from_ascii_str("To"), recipients.to_owned()));
let mailer = create_mailer();
// TODO: Add logging
// Send the email
match mailer.send(&email) {
Ok(_) => println!("Basic email sent!"),
@ -48,18 +54,3 @@ pub fn send_email(subject: String, recipient: String, body: String) {
}
}
}
pub fn send_emails(subject: String, recipients: Vec<String>, body: String) {
let username = var("EMAIL_USERNAME").expect("EMAIL_USERNAME not set");
// Build the email
let mut email = Message::builder()
.from(username.parse::<Mailbox>().unwrap())
.subject(subject)
.header(ContentType::TEXT_HTML)
.body(body);
for recipient in recipients {
email = email.to(recipient.parse::<Mailbox>().unwrap());
}
}

View File

@ -22,6 +22,9 @@ use sqlx::SqlitePool;
use std::collections::HashMap;
use uuid::Uuid;
use crate::user::get_useremails_by_role;
use crate::email::send_emails;
use super::{AppError, UserData};
fn get_client(hostname: String) -> Result<BasicClient, AppError> {
@ -201,16 +204,18 @@ pub async fn google_auth_return(
// Add public role
sqlx::query("INSERT INTO user_roles (created_at, created_by, updated_at, updated_by, user_id, role_id) VALUES (?, ?, ?, ?, ?, ?)")
.bind(now)
.bind(0 as i64)// Created by system
.bind(now)
.bind(0 as i64) // Updated by system
.bind(query.0)
.bind(now)
.bind(0 as i64)// Created by system
.bind(now)
.bind(0 as i64) // Updated by system
.bind(query.0)
.bind("1")
.execute(&db_pool)
.await?;
// TODO - send email to admin regarding new user registration
// send email to admin regarding new user registration
let recipients = get_useremails_by_role("admin".to_string(), &db_pool).await;
send_emails("Jean-Marie website - New user registration".to_string(), recipients, "A new user has registered".to_string());
query.0
};

View File

@ -2,7 +2,6 @@ use std::net::SocketAddr;
use axum::{
middleware, routing::{get, get_service}, Extension, Router
};
use email::send_email;
use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
use sqlx::migrate::Migrator;
use tower_http::services::ServeDir;
@ -21,6 +20,7 @@ use google_oauth::{login, logout, google_auth_return};
use routes::{about, contact, cottagecalendar, dashboard, index, profile, user_profile, useradmin};
use user::{add_user_role, delete_user_role, UserData};
use wishlist::{user_wishlist, user_wishlist_add, user_wishlist_add_item, user_wishlist_bought_item, user_wishlist_received_item, wishlists};
//use email::send_emails;
#[derive(Clone)]
pub struct AppState {
@ -71,12 +71,13 @@ async fn main() {
.route("/logout", get(logout))
.route("/google_auth_return", get(google_auth_return))
.route_layer(middleware::from_fn_with_state(app_state.db_pool.clone(), inject_user_data))
.with_state(app_state.db_pool)
.with_state(app_state.db_pool.clone())
.layer(Extension(user_data))
;
// Send email indicating server has started
//send_email("Server started".to_string(), "chris@jean-marie.ca".to_string(), "Server has been started".to_string());
//let recipients = get_useremails_by_role("admin".to_string(), &app_state.db_pool).await;
//send_emails("Server started".to_string(), recipients, "Server has been started".to_string());
// run it
let addr = SocketAddr::from(([0, 0, 0, 0], 40192));

View File

@ -8,11 +8,11 @@ use chrono::Utc;
///User related structs and functions
use serde::{Deserialize, Serialize};
use sqlx::{prelude::FromRow, SqlitePool};
use sqlx::{FromRow, SqlitePool};
use crate::middlewares::is_authorized;
#[derive(Default, Clone, Debug, FromRow, Serialize, Deserialize)]
#[derive(Default, Clone, Debug, Serialize, Deserialize, FromRow)]
pub struct UserData {
pub id: i64,
pub created_at: i64,
@ -36,7 +36,7 @@ pub struct RoleData {
pub description: String,
}
#[derive(Default, Clone, Debug, FromRow, Serialize, Deserialize)]
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct UserRoles {
pub id: i64,
pub created_at: i64,
@ -47,7 +47,7 @@ pub struct UserRoles {
pub role_id: i64,
}
#[derive(Default, Clone, Debug, FromRow, Serialize, Deserialize)]
#[derive(Default, Clone, Debug, Serialize, Deserialize, FromRow)]
pub struct UserRolesDisplay {
pub id: i64,
pub created_at: i64,
@ -60,7 +60,7 @@ pub struct UserRolesDisplay {
pub role_name: String,
}
#[derive(Default, Clone, Debug, FromRow, Serialize, Deserialize)]
#[derive(Default, Clone, Debug, Serialize, Deserialize, FromRow)]
pub struct UserWishlistItem {
pub id: i64,
pub created_at: i64,
@ -165,7 +165,8 @@ pub async fn delete_user_role(
pub async fn get_user_wishlist_items(user_id: i64, db_pool: &SqlitePool) -> Vec<UserWishlistItem> {
// Get wish list items for the user
let user_wishlist_items = sqlx::query_as(
r#"select id, created_at, created_by, updated_at, updated_by, user_id, item, item_url, purchased_by, received_at from wishlist_items where user_id = ?"#
r#"select id, created_at, created_by, updated_at, updated_by, user_id, item, item_url, purchased_by, received_at
from wishlist_items where user_id = ?"#
)
.bind(user_id)
.fetch_all(db_pool)
@ -174,3 +175,13 @@ pub async fn get_user_wishlist_items(user_id: i64, db_pool: &SqlitePool) -> Vec<
user_wishlist_items
}
pub async fn get_useremails_by_role(role_name: String, db_pool: &SqlitePool) -> String {
let useremails: String = sqlx::query_scalar(r#"select group_concat(u.email) as email from user_roles ur, roles r, users u where u.id = ur.user_id and r.id = ur.role_id and r.name = ?"#)
.bind(role_name)
.fetch_one(db_pool)
.await
.unwrap();
useremails
}