Unsubscribe option available on website

This commit is contained in:
Alphonse Paix
2025-09-22 15:44:02 +02:00
parent a37123a32d
commit f1ce77a762
21 changed files with 400 additions and 91 deletions

View File

@@ -41,28 +41,33 @@ pub async fn subscribe(
.begin()
.await
.context("Failed to acquire a Postgres connection from the pool.")?;
let subscriber_id = insert_subscriber(&mut transaction, &new_subscriber)
if let Some(subscriber_id) = insert_subscriber(&mut transaction, &new_subscriber)
.await
.context("Failed to insert new subscriber in the database.")?;
let subscription_token = generate_token();
store_token(&mut transaction, &subscription_token, &subscriber_id)
.context("Failed to insert new subscriber in the database.")
.map_err(AppError::unexpected_message)?
{
let subscription_token = generate_token();
store_token(&mut transaction, &subscription_token, &subscriber_id)
.await
.context("Failed to store the confirmation token for a new subscriber.")
.map_err(AppError::unexpected_message)?;
send_confirmation_email(
&email_client,
&new_subscriber,
&base_url,
&subscription_token,
)
.await
.context("Failed to store the confirmation token for a new subscriber.")?;
send_confirmation_email(
&email_client,
&new_subscriber,
&base_url,
&subscription_token,
)
.await
.context("Failed to send a confirmation email.")?;
.context("Failed to send a confirmation email.")?;
transaction
.commit()
.await
.context("Failed to commit the database transaction to store a new subscriber.")?;
}
transaction
.commit()
.await
.context("Failed to commit the database transaction to store a new subscriber.")?;
let template = MessageTemplate::Success {
message: "A confirmation email has been sent.".to_string(),
message: "You'll receive a confirmation email shortly.".to_string(),
};
Ok(Html(template.render().unwrap()).into_response())
}
@@ -74,7 +79,15 @@ pub async fn subscribe(
pub async fn insert_subscriber(
transaction: &mut Transaction<'_, Postgres>,
new_subscriber: &NewSubscriber,
) -> Result<Uuid, sqlx::Error> {
) -> Result<Option<Uuid>, sqlx::Error> {
let query = sqlx::query!(
"SELECT id FROM subscriptions WHERE email = $1",
new_subscriber.email.as_ref()
);
let existing = transaction.fetch_optional(query).await?;
if existing.is_some() {
return Ok(None);
}
let subscriber_id = Uuid::new_v4();
let query = sqlx::query!(
r#"
@@ -86,7 +99,7 @@ pub async fn insert_subscriber(
Utc::now()
);
transaction.execute(query).await?;
Ok(subscriber_id)
Ok(Some(subscriber_id))
}
#[tracing::instrument(