pub private_instance: Option<bool>,
pub default_theme: Option<String>,
pub default_post_listing_type: Option<String>,
+ pub application_email_admins: Option<bool>,
pub auth: Sensitive<String>,
pub hide_modlog_mod_names: Option<bool>,
}
pub default_theme: Option<String>,
pub default_post_listing_type: Option<String>,
pub legal_information: Option<String>,
+ pub application_email_admins: Option<bool>,
pub auth: Sensitive<String>,
pub hide_modlog_mod_names: Option<bool>,
}
}
pub fn get_interface_language(user: &LocalUserView) -> Lang {
- let user_lang = LanguageId::new(user.local_user.interface_language.clone());
- Lang::from_language_id(&user_lang).unwrap_or_else(|| {
+ lang_str_to_lang(&user.local_user.interface_language)
+}
+
+pub fn get_interface_language_from_settings(user: &LocalUserSettingsView) -> Lang {
+ lang_str_to_lang(&user.local_user.interface_language)
+}
+
+fn lang_str_to_lang(lang: &str) -> Lang {
+ let lang_id = LanguageId::new(lang);
+ Lang::from_language_id(&lang_id).unwrap_or_else(|| {
let en = LanguageId::new("en");
Lang::from_language_id(&en).expect("default language")
})
send_email(&subject, email, &user.person.name, &body, settings)
}
+/// Send a new applicant email notification to all admins
+pub async fn send_new_applicant_email_to_admins(
+ applicant_username: &str,
+ pool: &DbPool,
+ settings: &Settings,
+) -> Result<(), LemmyError> {
+ // Collect the admins with emails
+ let admins = blocking(pool, move |conn| {
+ LocalUserSettingsView::list_admins_with_emails(conn)
+ })
+ .await??;
+
+ let applications_link = &format!(
+ "{}/registration_applications",
+ settings.get_protocol_and_hostname(),
+ );
+
+ for admin in &admins {
+ let email = &admin.local_user.email.to_owned().expect("email");
+ let lang = get_interface_language_from_settings(admin);
+ let subject = lang.new_application_subject(applicant_username, &settings.hostname);
+ let body = lang.new_application_body(applications_link);
+ send_email(&subject, email, &admin.person.name, &body, settings)?;
+ }
+ Ok(())
+}
+
pub async fn check_registration_application(
site: &Site,
local_user_view: &LocalUserView,
public_key: Some(keypair.public_key),
default_theme: data.default_theme.clone(),
default_post_listing_type: data.default_post_listing_type.clone(),
+ application_email_admins: data.application_email_admins,
hide_modlog_mod_names: data.hide_modlog_mod_names,
..SiteForm::default()
};
default_theme: data.default_theme.clone(),
default_post_listing_type: data.default_post_listing_type.clone(),
legal_information,
+ application_email_admins: data.application_email_admins,
hide_modlog_mod_names: data.hide_modlog_mod_names,
..SiteForm::default()
};
use actix_web::web::Data;
use lemmy_api_common::{
person::{LoginResponse, Register},
- utils::{blocking, honeypot_check, password_length_check, send_verification_email},
+ utils::{
+ blocking,
+ honeypot_check,
+ password_length_check,
+ send_new_applicant_email_to_admins,
+ send_verification_email,
+ },
};
use lemmy_apub::{
generate_inbox_url,
let (mut email_verification, mut require_application) = (false, false);
// Make sure site has open registration
- if let Ok(site) = blocking(context.pool(), Site::read_local_site).await? {
+ let site = blocking(context.pool(), Site::read_local_site).await?;
+ if let Ok(site) = &site {
if !site.open_registration {
return Err(LemmyError::from_message("registration_closed"));
}
.await??;
}
+ // Email the admins
+ if site.map(|s| s.application_email_admins).unwrap_or(false) {
+ send_new_applicant_email_to_admins(&data.username, context.pool(), context.settings())
+ .await?;
+ }
+
let mut login_response = LoginResponse {
jwt: None,
registration_created: false,
default_theme -> Text,
default_post_listing_type -> Text,
legal_information -> Nullable<Text>,
+ application_email_admins -> Bool,
hide_modlog_mod_names -> Bool,
}
}
pub default_theme: String,
pub default_post_listing_type: String,
pub legal_information: Option<String>,
+ pub application_email_admins: bool,
pub hide_modlog_mod_names: bool,
}
pub default_theme: Option<String>,
pub default_post_listing_type: Option<String>,
pub legal_information: Option<Option<String>>,
+ pub application_email_admins: Option<bool>,
pub hide_modlog_mod_names: Option<bool>,
}
local_user::{LocalUser, LocalUserSettings},
person::{Person, PersonSafe},
},
- traits::{ToSafe, ToSafeSettings},
+ traits::{ToSafe, ToSafeSettings, ViewToVec},
utils::functions::lower,
};
counts,
})
}
+
+ pub fn list_admins_with_emails(conn: &mut PgConnection) -> Result<Vec<Self>, Error> {
+ let res = local_user::table
+ .filter(person::admin.eq(true))
+ .filter(local_user::email.is_not_null())
+ .inner_join(person::table)
+ .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
+ .select((
+ LocalUser::safe_settings_columns_tuple(),
+ Person::safe_columns_tuple(),
+ person_aggregates::all_columns,
+ ))
+ .load::<LocalUserSettingsViewTuple>(conn)?;
+
+ Ok(LocalUserSettingsView::from_tuple_to_vec(res))
+ }
+}
+
+impl ViewToVec for LocalUserSettingsView {
+ type DbTuple = LocalUserSettingsViewTuple;
+ fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
+ items
+ .into_iter()
+ .map(|a| Self {
+ local_user: a.0,
+ person: a.1,
+ counts: a.2,
+ })
+ .collect::<Vec<Self>>()
+ }
}
-Subproject commit 3f86b5c40796fa83054e2226e36effff3b93198a
+Subproject commit f5d6f0eabafd559417bf8f203fd655f7858bffcf
--- /dev/null
+alter table site drop column application_email_admins;
--- /dev/null
+-- Adding a field to email admins for new applications
+alter table site add column application_email_admins boolean not null default false;