diff --git a/sqlx-data.json b/sqlx-data.json index 328f054be..ca235420a 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -1014,19 +1014,6 @@ }, "query": "\n SELECT mod_id FROM versions WHERE id = $1\n " }, - "16b3ac53ef5e94f51ab39484add21e2f76d49015917dc877560607a31f5537e9": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET email = $1\n WHERE (id = $2)\n " - }, "177716d2b04fd2a2b63b2e14c8ffdfa554d84254b14053496c118dec24bf5049": { "describe": { "columns": [], @@ -3483,6 +3470,19 @@ }, "query": "\n UPDATE mods\n SET loaders = (\n SELECT COALESCE(ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null), array[]::varchar[])\n FROM versions v\n INNER JOIN loaders_versions lv ON lv.version_id = v.id\n INNER JOIN loaders l on lv.loader_id = l.id\n WHERE v.mod_id = mods.id AND v.status != ALL($2)\n )\n WHERE id = $1\n " }, + "6ba05a1b6ddc18f43ccffd5ef2d9349ce73d0da35479dcf10b6d20b57aa78728": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + } + }, + "query": "\n UPDATE users\n SET email = $1\n WHERE kratos_id = $2\n " + }, "6c4a42c263ae2787744aa6903e3cd85e90beaa5bea7ba78b45dbf55ce007753d": { "describe": { "columns": [ diff --git a/src/routes/v2/admin.rs b/src/routes/v2/admin.rs index be8208347..3949feea4 100644 --- a/src/routes/v2/admin.rs +++ b/src/routes/v2/admin.rs @@ -21,6 +21,7 @@ pub fn config(cfg: &mut web::ServiceConfig) { .service(count_download) .service(add_minos_user) .service(edit_github_id) + .service(edit_email) .service(get_legacy_account) .service(process_payout), ); @@ -78,6 +79,38 @@ pub async fn edit_github_id( Ok(HttpResponse::Ok().finish()) } +// Update a user's email ID by their kratos id +// email ids should be kept in Minos, but email is duplicated in Labrinth for legacy support (and to avoid Minos calls) +// This should not be directly useable by applications, only by the Minos backend +// user id is passed in path, email is passed in body +#[derive(Deserialize)] +pub struct EditEmail { + email: String, +} +#[post("_edit_email/{kratos_id}", guard = "admin_key_guard")] +pub async fn edit_email( + pool: web::Data, + kratos_id: web::Path, + email: web::Json, +) -> Result { + let email = email.into_inner().email; + + let mut transaction = pool.begin().await?; + sqlx::query!( + " + UPDATE users + SET email = $1 + WHERE kratos_id = $2 + ", + email, + kratos_id.into_inner() + ) + .execute(&mut transaction) + .await?; + transaction.commit().await?; + Ok(HttpResponse::Ok().finish()) +} + #[get("_legacy_account/{github_id}", guard = "admin_key_guard")] pub async fn get_legacy_account( diff --git a/src/routes/v2/users.rs b/src/routes/v2/users.rs index 11ffe12a3..14666e6a1 100644 --- a/src/routes/v2/users.rs +++ b/src/routes/v2/users.rs @@ -186,13 +186,6 @@ pub struct EditUser { skip_serializing_if = "Option::is_none", with = "::serde_with::rust::double_option" )] - #[validate(email, length(max = 2048))] - pub email: Option>, - #[serde( - default, - skip_serializing_if = "Option::is_none", - with = "::serde_with::rust::double_option" - )] #[validate(length(max = 160))] pub bio: Option>, pub role: Option, @@ -290,20 +283,6 @@ pub async fn user_edit( .await?; } - if let Some(email) = &new_user.email { - sqlx::query!( - " - UPDATE users - SET email = $1 - WHERE (id = $2) - ", - email.as_deref(), - id as crate::database::models::ids::UserId, - ) - .execute(&mut *transaction) - .await?; - } - if let Some(role) = &new_user.role { if !user.role.is_admin() { return Err(ApiError::CustomAuthentication(