mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-09 03:21:23 +00:00
resend client config
This commit is contained in:
1 parent
5a688e1558
commit
2691f8b669
5 files changed
+56
-16
No files matched your search
@@ -1,2 +1,2 @@
|
||||
mod send_password_reset_email;
|
||||
mod get_password_reset_url;
|
||||
pub mod send_password_reset_email;
|
||||
pub mod get_password_reset_url;
|
||||
@@ -6,27 +6,37 @@ use resend_rs::Resend;
|
||||
use server_environment::ServerEnvironment;
|
||||
|
||||
pub struct SendPasswordResetEmailArgs<'a> {
|
||||
email_address_destination: &'a str,
|
||||
verification_token: &'a str,
|
||||
resend_client: &'a Resend,
|
||||
server_environment: ServerEnvironment,
|
||||
domain_branding: DomainBranding,
|
||||
pub email_address_destination: &'a str,
|
||||
pub verification_token: &'a str,
|
||||
pub resend_api_key: &'a str,
|
||||
pub server_environment: ServerEnvironment,
|
||||
pub domain_branding: DomainBranding,
|
||||
}
|
||||
|
||||
pub async fn send_password_reset_email(
|
||||
args: SendPasswordResetEmailArgs<'_>
|
||||
) -> AnyhowResult<()> {
|
||||
let resend = Resend::new("re_xxxxxxxxx");
|
||||
let resend = Resend::new(&args.resend_api_key);
|
||||
|
||||
let from = "ArtCraft <noreply@getartcraft.com>";
|
||||
let to = [args.email_address_destination];
|
||||
|
||||
let subject = "ArtCraft Password Reset";
|
||||
|
||||
let from_address = match args.domain_branding {
|
||||
DomainBranding::ArtCraftDotAi |
|
||||
DomainBranding::GetArtCraft => "ArtCraft <noreply@getartcraft.com>",
|
||||
DomainBranding::FakeYou => "FakeYou <noreply@fakeyou.com>",
|
||||
DomainBranding::Storyteller => "FakeYou <noreply@fakeyou.com>",
|
||||
};
|
||||
|
||||
let url = match (args.domain_branding, args.server_environment) {
|
||||
// Legacy FakeYou
|
||||
(DomainBranding::FakeYou, ServerEnvironment::Development) => PasswordResetLocation::FakeYouDevelopment,
|
||||
(DomainBranding::FakeYou, ServerEnvironment::Production) => PasswordResetLocation::FakeYouProduction,
|
||||
(_, _) => PasswordResetLocation::ArtCraftProduction,
|
||||
// Everything else "development" is ArtCraft Development
|
||||
(_, ServerEnvironment::Development) => PasswordResetLocation::ArtCraftDevelopment,
|
||||
// Everything else "production" is ArtCraft Production
|
||||
(_, ServerEnvironment::Production) => PasswordResetLocation::ArtCraftProduction,
|
||||
};
|
||||
|
||||
let link = get_password_reset_url(args.verification_token, url);
|
||||
@@ -45,10 +55,10 @@ pub async fn send_password_reset_email(
|
||||
Storyteller.ai (FakeYou) Team
|
||||
"#);
|
||||
|
||||
let email = CreateEmailBaseOptions::new(from, to, subject)
|
||||
let email = CreateEmailBaseOptions::new(from_address, to, subject)
|
||||
.with_html(&html_message);
|
||||
|
||||
let _email = args.resend_client.emails.send(email).await?;
|
||||
let _email = resend.emails.send(email).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+20
-3
@@ -2,7 +2,7 @@ use std::fmt::Display;
|
||||
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::{web, HttpRequest, HttpResponse, ResponseError};
|
||||
use log::{error, warn};
|
||||
use log::{error, info, warn};
|
||||
use serde::Deserialize;
|
||||
use sqlx::MySqlPool;
|
||||
use strum_macros::Display;
|
||||
@@ -20,6 +20,9 @@ use mysql_queries::queries::users::user::get::lookup_user_for_login_by_email::lo
|
||||
use mysql_queries::queries::users::user::get::lookup_user_for_login_by_username::lookup_user_for_login_by_username;
|
||||
use mysql_queries::queries::users::user_password_resets::create_password_reset_request::create_password_reset;
|
||||
use server_environment::ServerEnvironment;
|
||||
use crate::email::send_password_reset_email::{send_password_reset_email, SendPasswordResetEmailArgs};
|
||||
use crate::http_server::requests::get_request_domain_branding::{get_request_domain_branding, DomainBranding};
|
||||
use crate::state::server_state::ServerState;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PasswordResetRequestedRequest {
|
||||
@@ -81,7 +84,8 @@ pub async fn password_reset_request_handler(
|
||||
http_request: HttpRequest,
|
||||
request: web::Json<PasswordResetRequestedRequest>,
|
||||
mysql_pool: web::Data<MySqlPool>,
|
||||
_server_environment: web::Data<ServerEnvironment>,
|
||||
server_environment: web::Data<ServerEnvironment>,
|
||||
server_state: web::Data<ServerState>,
|
||||
_sender: web::Data<SmtpEmailSender>,
|
||||
) -> Result<HttpResponse, PasswordResetRequestedErrorResponse> {
|
||||
|
||||
@@ -134,7 +138,7 @@ pub async fn password_reset_request_handler(
|
||||
email_category: EmailCategory::PasswordReset,
|
||||
maybe_email_args: Some(EmailSenderJobArgs {
|
||||
args: Some(PolymorphicEmailSenderJobArgs::Pr(EmailJobPasswordResetArgs {
|
||||
password_reset_secret_key: Some(secret_key),
|
||||
password_reset_secret_key: Some(secret_key.clone()),
|
||||
})),
|
||||
}),
|
||||
ietf_language_tag,
|
||||
@@ -153,7 +157,20 @@ pub async fn password_reset_request_handler(
|
||||
PasswordResetRequestedRequestError::Internal
|
||||
})?;
|
||||
|
||||
let domain_branding = get_request_domain_branding(&http_request)
|
||||
.unwrap_or(DomainBranding::GetArtCraft);
|
||||
|
||||
let server_environment = **server_environment;
|
||||
|
||||
info!("Sending password reset email...");
|
||||
|
||||
send_password_reset_email(SendPasswordResetEmailArgs {
|
||||
email_address_destination: &user.email_address,
|
||||
verification_token: &secret_key,
|
||||
resend_api_key: &server_state.resend.api_key,
|
||||
server_environment,
|
||||
domain_branding,
|
||||
}).await?;
|
||||
|
||||
success_response()
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ use crate::http_server::web_utils::handle_multipart_error::handle_multipart_erro
|
||||
use crate::http_server::web_utils::scoped_temp_dir_creator::ScopedTempDirCreator;
|
||||
use crate::state::certs::google_sign_in_cert::GoogleSignInCert;
|
||||
use crate::state::memory_cache::model_token_to_info_cache::ModelTokenToInfoCache;
|
||||
use crate::state::server_state::{DurableInMemoryCaches, EnvConfig, EphemeralInMemoryCaches, FalData, InMemoryCaches, OpenAiData, ServerInfo, ServerState, StaticFeatureFlags, StripeSettings, TrollBans};
|
||||
use crate::state::server_state::{DurableInMemoryCaches, EnvConfig, EphemeralInMemoryCaches, FalData, InMemoryCaches, OpenAiData, ResendData, ServerInfo, ServerState, StaticFeatureFlags, StripeSettings, TrollBans};
|
||||
use crate::threads::db_health_checker_thread::db_health_check_status::HealthCheckStatus;
|
||||
use crate::threads::db_health_checker_thread::db_health_checker_thread::db_health_checker_thread;
|
||||
use crate::threads::poll_ip_banlist_thread::poll_ip_bans;
|
||||
@@ -402,6 +402,8 @@ async fn main() -> AnyhowResult<()> {
|
||||
|
||||
let openai_api_key= easyenv::get_env_string_required("OPENAI_API_KEY")?;
|
||||
|
||||
let resend_api_key = easyenv::get_env_string_required("RESEND_API_KEY")?;
|
||||
|
||||
let startup_time = Utc::now();
|
||||
|
||||
let server_state = ServerState {
|
||||
@@ -460,6 +462,9 @@ async fn main() -> AnyhowResult<()> {
|
||||
openai: OpenAiData {
|
||||
api_key: openai_api_key,
|
||||
},
|
||||
resend: ResendData {
|
||||
api_key: resend_api_key,
|
||||
},
|
||||
caches: InMemoryCaches {
|
||||
durable: DurableInMemoryCaches {
|
||||
model_token_info: model_token_info_cache,
|
||||
|
||||
@@ -95,6 +95,8 @@ pub struct ServerState {
|
||||
|
||||
pub openai: OpenAiData,
|
||||
|
||||
pub resend: ResendData,
|
||||
|
||||
/// Where to store audio uploads for w2l
|
||||
pub audio_uploads_bucket_root: String,
|
||||
|
||||
@@ -314,3 +316,9 @@ pub struct FalData {
|
||||
pub struct OpenAiData {
|
||||
pub api_key: String,
|
||||
}
|
||||
|
||||
/// Resend integration
|
||||
#[derive(Clone)]
|
||||
pub struct ResendData {
|
||||
pub api_key: String,
|
||||
}
|
||||
Reference in new issue
Block a user