&context.settings().get_protocol_and_hostname(),
)?;
+ if let Some(email) = &data.email {
+ if LocalUser::is_email_taken(context.pool(), email).await? {
+ return Err(LemmyError::from_message("email_already_exists"));
+ }
+ }
+
// We have to create both a person, and local_user
// Register the new person
.accepted_application(accepted_application)
.build();
- let inserted_local_user = match LocalUser::create(context.pool(), &local_user_form).await {
- Ok(lu) => lu,
- Err(e) => {
- let err_type = if e.to_string()
- == "duplicate key value violates unique constraint \"local_user_email_key\""
- {
- "email_already_exists"
- } else {
- "user_already_exists"
- };
-
- // If the local user creation errored, then delete that person
- Person::delete(context.pool(), inserted_person.id).await?;
-
- return Err(LemmyError::from_error_message(e, err_type));
- }
- };
+ let inserted_local_user = LocalUser::create(context.pool(), &local_user_form).await?;
if local_site.site_setup && require_registration_application {
// Create the registration application
matrix_user_id: person.matrix_user_id,
instance_id,
};
- let person = DbPerson::create(context.pool(), &person_form).await?;
+ let person = DbPerson::upsert(context.pool(), &person_form).await?;
Ok(person.into())
}
newtypes::LocalUserId,
schema::local_user::dsl::{
accepted_application,
+ email,
email_verified,
local_user,
password_encrypted,
.get_results::<Self>(conn)
.await
}
+
+ pub async fn is_email_taken(pool: &DbPool, email_: &str) -> Result<bool, Error> {
+ use diesel::dsl::{exists, select};
+ let conn = &mut get_conn(pool).await?;
+ select(exists(local_user.filter(email.eq(email_))))
+ .get_result(conn)
+ .await
+ }
}
#[async_trait]
let local_user_ = insert_into(local_user)
.values(form_with_encrypted_password)
.get_result::<Self>(conn)
- .await
- .expect("couldnt create local user");
+ .await?;
let site_languages = SiteLanguage::read_local_raw(pool).await;
if let Ok(langs) = site_languages {
let conn = &mut get_conn(pool).await?;
insert_into(person::table)
.values(form)
- .on_conflict(person::actor_id)
- .do_update()
- .set(form)
.get_result::<Self>(conn)
.await
}
}
impl Person {
+ /// Update or insert the person.
+ ///
+ /// This is necessary for federation, because Activitypub doesnt distinguish between these actions.
+ pub async fn upsert(pool: &DbPool, form: &PersonInsertForm) -> Result<Self, Error> {
+ let conn = &mut get_conn(pool).await?;
+ insert_into(person::table)
+ .values(form)
+ .on_conflict(person::actor_id)
+ .do_update()
+ .set(form)
+ .get_result::<Self>(conn)
+ .await
+ }
pub async fn delete_account(pool: &DbPool, person_id: PersonId) -> Result<Person, Error> {
let conn = &mut get_conn(pool).await?;