feat: require verified email to publish, to prevent spam (#6777)

* feat: require verified email to create projects, collections and organizations

* fix(labrinth): fix tests

* chore: fmt

* chore: intl
This commit is contained in:
François-Xavier Talbot
2026-07-20 02:51:16 +00:00
committed by GitHub
parent c579925f03
commit 7144f08f0f
10 changed files with 99 additions and 11 deletions
+5 -1
View File
@@ -1,5 +1,7 @@
use crate::auth::checks::is_visible_collection;
use crate::auth::{filter_visible_collections, get_user_from_headers};
use crate::auth::{
filter_visible_collections, get_user_from_headers, require_verified_email,
};
use crate::database::PgPool;
use crate::database::models::{
collection_item, generate_collection_id, project_item,
@@ -76,6 +78,8 @@ pub async fn collection_create(
.await?
.1;
require_verified_email(&current_user)?;
let limits =
UserLimits::get_for_collections(&current_user, &client).await?;
if limits.current >= limits.max {
+5 -1
View File
@@ -2,7 +2,9 @@ use std::collections::HashMap;
use super::ApiError;
use crate::auth::checks::is_visible_organization;
use crate::auth::{filter_visible_projects, get_user_from_headers};
use crate::auth::{
filter_visible_projects, get_user_from_headers, require_verified_email,
};
use crate::database::PgPool;
use crate::database::models::team_item::DBTeamMember;
use crate::database::models::{
@@ -131,6 +133,8 @@ pub async fn organization_create(
.await?
.1;
require_verified_email(&current_user)?;
let limits =
UserLimits::get_for_organizations(&current_user, &pool).await?;
if limits.current >= limits.max {
@@ -1,5 +1,7 @@
use super::version_creation::{InitialVersionData, try_create_version_fields};
use crate::auth::{AuthenticationError, get_user_from_headers};
use crate::auth::{
AuthenticationError, get_user_from_headers, require_verified_email,
};
use crate::database::PgPool;
use crate::database::PgTransaction;
use crate::database::models::loader_fields::{
@@ -107,6 +109,9 @@ impl From<crate::routes::ApiError> for CreateError {
crate::routes::ApiError::CustomAuthentication(err) => {
Self::CustomAuthenticationError(err)
}
crate::routes::ApiError::Auth(err) => {
Self::CustomAuthenticationError(format!("{err:#}"))
}
crate::routes::ApiError::InvalidInput(err)
| crate::routes::ApiError::Validation(err) => {
Self::InvalidInput(err)
@@ -491,6 +496,8 @@ async fn project_create_inner(
)
.await?;
require_verified_email(&current_user)?;
let limits = UserLimits::get_for_projects(&current_user, pool).await?;
if limits.current >= limits.max {
return Err(CreateError::LimitReached);
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use validator::Validate;
use crate::{
auth::get_user_from_headers,
auth::{get_user_from_headers, require_verified_email},
database::{
PgPool,
models::{
@@ -140,6 +140,8 @@ pub async fn create(
.await
.map_err(ApiError::from)?;
require_verified_email(&user)?;
let limits = UserLimits::get_for_projects(&user, &db)
.await
.map_err(ApiError::from)?;