fix(labrinth): retire Sendy for new email newsletter subscriptions (#4073)
* tweak(frontend): do not sign up for the newsletter by default * fix(labrinth): retire Sendy for new email newsletter subscriptions
This commit is contained in:
parent
175b90be5a
commit
c7d0839bfb
@ -218,7 +218,7 @@ const username = ref("");
|
||||
const password = ref("");
|
||||
const confirmPassword = ref("");
|
||||
const token = ref("");
|
||||
const subscribe = ref(true);
|
||||
const subscribe = ref(false);
|
||||
|
||||
async function createAccount() {
|
||||
startLoading();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO users (\n id, username, email,\n avatar_url, raw_avatar_url, bio, created,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, paypal_id, paypal_country, paypal_email,\n venmo_handle, stripe_customer_id, allow_friend_requests\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7,\n $8, $9, $10, $11, $12, $13,\n $14, $15, $16, $17, $18, $19, $20, $21\n )\n ",
|
||||
"query": "\n INSERT INTO users (\n id, username, email,\n avatar_url, raw_avatar_url, bio, created,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, paypal_id, paypal_country, paypal_email,\n venmo_handle, stripe_customer_id, allow_friend_requests, is_subscribed_to_newsletter\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7,\n $8, $9, $10, $11, $12, $13,\n $14, $15, $16, $17, $18, $19, $20, $21, $22\n )\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@ -25,10 +25,11 @@
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Bool",
|
||||
"Bool"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "32fa1030a3a69f6bc36c6ec916ba8d0724dfd683576629ab05f5df321d5f9a55"
|
||||
"hash": "010c69fa61e1329156020b251e75d46bc09344c1846b3098accce5801e571e5e"
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT id, email,\n avatar_url, raw_avatar_url, username, bio,\n created, role, badges,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email,\n venmo_handle, stripe_customer_id, allow_friend_requests\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n ",
|
||||
"query": "\n SELECT id, email,\n avatar_url, raw_avatar_url, username, bio,\n created, role, badges,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email,\n venmo_handle, stripe_customer_id, allow_friend_requests, is_subscribed_to_newsletter\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@ -122,6 +122,11 @@
|
||||
"ordinal": 23,
|
||||
"name": "allow_friend_requests",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"name": "is_subscribed_to_newsletter",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@ -154,8 +159,9 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "b5857aafa522ca62294bc296fb6cddd862eca2889203e43b4962df07ba1221a0"
|
||||
"hash": "5fcdeeeb820ada62e10feb0beefa29b0535241bbb6d74143925e16cf8cd720c4"
|
||||
}
|
||||
14
apps/labrinth/.sqlx/query-c960b09ddc19530383f143c349c7e34bf813ddbfb88bf31b9863078bc48c8623.json
generated
Normal file
14
apps/labrinth/.sqlx/query-c960b09ddc19530383f143c349c7e34bf813ddbfb88bf31b9863078bc48c8623.json
generated
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE users\n SET is_subscribed_to_newsletter = TRUE\n WHERE id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "c960b09ddc19530383f143c349c7e34bf813ddbfb88bf31b9863078bc48c8623"
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
ALTER TABLE users ADD COLUMN is_subscribed_to_newsletter BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
@ -1,6 +1,6 @@
|
||||
use super::AuthProvider;
|
||||
use crate::auth::AuthenticationError;
|
||||
use crate::database::models::user_item;
|
||||
use crate::database::models::{DBUser, user_item};
|
||||
use crate::database::redis::RedisPool;
|
||||
use crate::models::pats::Scopes;
|
||||
use crate::models::users::User;
|
||||
@ -44,17 +44,16 @@ where
|
||||
Ok(Some((scopes, User::from_full(db_user))))
|
||||
}
|
||||
|
||||
pub async fn get_user_from_headers<'a, E>(
|
||||
pub async fn get_full_user_from_headers<'a, E>(
|
||||
req: &HttpRequest,
|
||||
executor: E,
|
||||
redis: &RedisPool,
|
||||
session_queue: &AuthQueue,
|
||||
required_scopes: Scopes,
|
||||
) -> Result<(Scopes, User), AuthenticationError>
|
||||
) -> Result<(Scopes, DBUser), AuthenticationError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
// Fetch DB user record and minos user from headers
|
||||
let (scopes, db_user) = get_user_record_from_bearer_token(
|
||||
req,
|
||||
None,
|
||||
@ -65,13 +64,33 @@ where
|
||||
.await?
|
||||
.ok_or_else(|| AuthenticationError::InvalidCredentials)?;
|
||||
|
||||
let user = User::from_full(db_user);
|
||||
|
||||
if !scopes.contains(required_scopes) {
|
||||
return Err(AuthenticationError::InvalidCredentials);
|
||||
}
|
||||
|
||||
Ok((scopes, user))
|
||||
Ok((scopes, db_user))
|
||||
}
|
||||
|
||||
pub async fn get_user_from_headers<'a, E>(
|
||||
req: &HttpRequest,
|
||||
executor: E,
|
||||
redis: &RedisPool,
|
||||
session_queue: &AuthQueue,
|
||||
required_scopes: Scopes,
|
||||
) -> Result<(Scopes, User), AuthenticationError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
let (scopes, db_user) = get_full_user_from_headers(
|
||||
req,
|
||||
executor,
|
||||
redis,
|
||||
session_queue,
|
||||
required_scopes,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok((scopes, User::from_full(db_user)))
|
||||
}
|
||||
|
||||
pub async fn get_user_record_from_bearer_token<'a, 'b, E>(
|
||||
|
||||
@ -49,6 +49,8 @@ pub struct DBUser {
|
||||
pub badges: Badges,
|
||||
|
||||
pub allow_friend_requests: bool,
|
||||
|
||||
pub is_subscribed_to_newsletter: bool,
|
||||
}
|
||||
|
||||
impl DBUser {
|
||||
@ -63,13 +65,13 @@ impl DBUser {
|
||||
avatar_url, raw_avatar_url, bio, created,
|
||||
github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,
|
||||
email_verified, password, paypal_id, paypal_country, paypal_email,
|
||||
venmo_handle, stripe_customer_id, allow_friend_requests
|
||||
venmo_handle, stripe_customer_id, allow_friend_requests, is_subscribed_to_newsletter
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3, $4, $5,
|
||||
$6, $7,
|
||||
$8, $9, $10, $11, $12, $13,
|
||||
$14, $15, $16, $17, $18, $19, $20, $21
|
||||
$14, $15, $16, $17, $18, $19, $20, $21, $22
|
||||
)
|
||||
",
|
||||
self.id as DBUserId,
|
||||
@ -93,6 +95,7 @@ impl DBUser {
|
||||
self.venmo_handle,
|
||||
self.stripe_customer_id,
|
||||
self.allow_friend_requests,
|
||||
self.is_subscribed_to_newsletter,
|
||||
)
|
||||
.execute(&mut **transaction)
|
||||
.await?;
|
||||
@ -178,7 +181,7 @@ impl DBUser {
|
||||
created, role, badges,
|
||||
github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,
|
||||
email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email,
|
||||
venmo_handle, stripe_customer_id, allow_friend_requests
|
||||
venmo_handle, stripe_customer_id, allow_friend_requests, is_subscribed_to_newsletter
|
||||
FROM users
|
||||
WHERE id = ANY($1) OR LOWER(username) = ANY($2)
|
||||
",
|
||||
@ -212,6 +215,7 @@ impl DBUser {
|
||||
stripe_customer_id: u.stripe_customer_id,
|
||||
totp_secret: u.totp_secret,
|
||||
allow_friend_requests: u.allow_friend_requests,
|
||||
is_subscribed_to_newsletter: u.is_subscribed_to_newsletter,
|
||||
};
|
||||
|
||||
acc.insert(u.id, (Some(u.username), user));
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use crate::auth::email::send_email;
|
||||
use crate::auth::validate::get_user_record_from_bearer_token;
|
||||
use crate::auth::validate::{
|
||||
get_full_user_from_headers, get_user_record_from_bearer_token,
|
||||
};
|
||||
use crate::auth::{AuthProvider, AuthenticationError, get_user_from_headers};
|
||||
use crate::database::models::DBUser;
|
||||
use crate::database::models::flow_item::DBFlow;
|
||||
@ -232,6 +234,7 @@ impl TempUser {
|
||||
role: Role::Developer.to_string(),
|
||||
badges: Badges::default(),
|
||||
allow_friend_requests: true,
|
||||
is_subscribed_to_newsletter: false,
|
||||
}
|
||||
.insert(transaction)
|
||||
.await?;
|
||||
@ -1291,37 +1294,6 @@ pub async fn delete_auth_provider(
|
||||
Ok(HttpResponse::NoContent().finish())
|
||||
}
|
||||
|
||||
pub async fn sign_up_sendy(email: &str) -> Result<(), AuthenticationError> {
|
||||
let url = dotenvy::var("SENDY_URL")?;
|
||||
let id = dotenvy::var("SENDY_LIST_ID")?;
|
||||
let api_key = dotenvy::var("SENDY_API_KEY")?;
|
||||
let site_url = dotenvy::var("SITE_URL")?;
|
||||
|
||||
if url.is_empty() || url == "none" {
|
||||
tracing::info!("Sendy URL not set, skipping signup");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut form = HashMap::new();
|
||||
|
||||
form.insert("api_key", &*api_key);
|
||||
form.insert("email", email);
|
||||
form.insert("list", &*id);
|
||||
form.insert("referrer", &*site_url);
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
client
|
||||
.post(format!("{url}/subscribe"))
|
||||
.form(&form)
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?
|
||||
.text()
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn check_sendy_subscription(
|
||||
email: &str,
|
||||
) -> Result<bool, AuthenticationError> {
|
||||
@ -1456,6 +1428,9 @@ pub async fn create_account_with_password(
|
||||
role: Role::Developer.to_string(),
|
||||
badges: Badges::default(),
|
||||
allow_friend_requests: true,
|
||||
is_subscribed_to_newsletter: new_account
|
||||
.sign_up_newsletter
|
||||
.unwrap_or(false),
|
||||
}
|
||||
.insert(&mut transaction)
|
||||
.await?;
|
||||
@ -1476,10 +1451,6 @@ pub async fn create_account_with_password(
|
||||
&format!("Welcome to Modrinth, {}!", new_account.username),
|
||||
)?;
|
||||
|
||||
if new_account.sign_up_newsletter.unwrap_or(false) {
|
||||
sign_up_sendy(&new_account.email).await?;
|
||||
}
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(res))
|
||||
@ -2420,15 +2391,24 @@ pub async fn subscribe_newsletter(
|
||||
.await?
|
||||
.1;
|
||||
|
||||
if let Some(email) = user.email {
|
||||
sign_up_sendy(&email).await?;
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE users
|
||||
SET is_subscribed_to_newsletter = TRUE
|
||||
WHERE id = $1
|
||||
",
|
||||
user.id.0 as i64,
|
||||
)
|
||||
.execute(&**pool)
|
||||
.await?;
|
||||
|
||||
crate::database::models::DBUser::clear_caches(
|
||||
&[(user.id.into(), None)],
|
||||
&redis,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::NoContent().finish())
|
||||
} else {
|
||||
Err(ApiError::InvalidInput(
|
||||
"User does not have an email.".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[get("email/subscribe")]
|
||||
@ -2438,7 +2418,7 @@ pub async fn get_newsletter_subscription_status(
|
||||
redis: Data<RedisPool>,
|
||||
session_queue: Data<AuthQueue>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let user = get_user_from_headers(
|
||||
let user = get_full_user_from_headers(
|
||||
&req,
|
||||
&**pool,
|
||||
&redis,
|
||||
@ -2448,16 +2428,16 @@ pub async fn get_newsletter_subscription_status(
|
||||
.await?
|
||||
.1;
|
||||
|
||||
if let Some(email) = user.email {
|
||||
let is_subscribed = check_sendy_subscription(&email).await?;
|
||||
let is_subscribed = user.is_subscribed_to_newsletter
|
||||
|| if let Some(email) = user.email {
|
||||
check_sendy_subscription(&email).await?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"subscribed": is_subscribed
|
||||
})))
|
||||
} else {
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"subscribed": false
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
fn send_email_verify(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user