From 9c56ceb940dc080b3660dd2f2e317dfdfa567af4 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:06:22 +0000 Subject: [PATCH 01/11] chore(services/user): migrate user-team-list proto op --- Cargo.lock | 15 ++++ packages/api/actor/Cargo.toml | 2 + packages/api/actor/src/auth.rs | 13 ++-- packages/api/cloud/Cargo.toml | 2 + packages/api/cloud/src/auth.rs | 33 +++++---- packages/api/games/Cargo.toml | 2 + packages/api/games/src/auth.rs | 12 ++-- packages/api/group/Cargo.toml | 2 + packages/api/group/src/fetch/group.rs | 12 ++-- packages/api/group/src/route/groups.rs | 10 +-- packages/api/portal/Cargo.toml | 2 + packages/api/portal/src/build.rs | 11 +-- packages/common/convert/Cargo.toml | 2 + .../common/convert/src/convert/identity.rs | 4 +- packages/common/convert/src/fetch/group.rs | 13 ++-- packages/common/convert/src/fetch/identity.rs | 19 ++++-- packages/services/user/Cargo.toml | 1 + packages/services/user/src/ops/mod.rs | 1 + packages/services/user/src/ops/team_list.rs | 68 +++++++++++++++++++ packages/services/user/worker/Cargo.toml | 3 +- .../user/worker/src/workers/delete.rs | 16 +++-- 21 files changed, 191 insertions(+), 52 deletions(-) create mode 100644 packages/services/user/src/ops/team_list.rs diff --git a/Cargo.lock b/Cargo.lock index f50ebda890..fae559b2fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,6 +265,7 @@ dependencies = [ "build-list-for-env", "cdn-namespace-domain-create", "chirp-client", + "chirp-workflow", "chrono", "cloud-namespace-token-development-create", "cloud-namespace-token-public-create", @@ -313,6 +314,7 @@ dependencies = [ "upload-complete", "upload-get", "url", + "user", "user-get", "user-identity-get", "user-team-list", @@ -425,6 +427,7 @@ dependencies = [ "cdn-site-list-for-game", "cf-custom-hostname-list-for-namespace-id", "chirp-client", + "chirp-workflow", "chrono", "cloud-device-link-create", "cloud-game-config-create", @@ -511,6 +514,7 @@ dependencies = [ "upload-get", "upload-prepare", "url", + "user", "user-get", "user-identity-create", "user-identity-get", @@ -530,6 +534,7 @@ dependencies = [ "build-list-for-env", "cdn-namespace-domain-create", "chirp-client", + "chirp-workflow", "chrono", "cloud-namespace-token-development-create", "cloud-namespace-token-public-create", @@ -572,6 +577,7 @@ dependencies = [ "upload-complete", "upload-get", "url", + "user", "user-get", "user-identity-get", "user-team-list", @@ -585,6 +591,7 @@ dependencies = [ "api-helper", "async-trait", "chirp-client", + "chirp-workflow", "chrono", "faker-user", "futures-util", @@ -626,6 +633,7 @@ dependencies = [ "tracing-subscriber", "upload-prepare", "url", + "user", "user-get", "user-identity-get", "user-team-list", @@ -914,6 +922,7 @@ dependencies = [ "api-helper", "async-trait", "chirp-client", + "chirp-workflow", "chrono", "faker-user", "futures-util", @@ -946,6 +955,7 @@ dependencies = [ "tracing", "tracing-subscriber", "url", + "user", "user-get", "user-team-list", "user-token-create", @@ -11729,6 +11739,7 @@ version = "24.6.2-rc.1" dependencies = [ "cdn-namespace-get", "chirp-client", + "chirp-workflow", "chrono", "cluster", "game-get", @@ -11759,6 +11770,7 @@ dependencies = [ "team-validate", "tier", "types-proto", + "user", "user-get", "user-identity-get", "user-team-list", @@ -15914,6 +15926,7 @@ dependencies = [ "cluster", "linode", "rivet-config", + "serde", "server-spec", ] @@ -16080,6 +16093,7 @@ version = "24.6.2-rc.1" dependencies = [ "chirp-client", "chirp-worker", + "chirp-workflow", "chrono", "faker-user", "game-get", @@ -16095,6 +16109,7 @@ dependencies = [ "upload-get", "upload-list-for-user", "upload-prepare", + "user", "user-get", "user-identity-delete", "user-profile-validate", diff --git a/packages/api/actor/Cargo.toml b/packages/api/actor/Cargo.toml index 3a18e44134..c0a80b6f02 100644 --- a/packages/api/actor/Cargo.toml +++ b/packages/api/actor/Cargo.toml @@ -8,6 +8,7 @@ edition.workspace = true [dependencies] api-helper.workspace = true chirp-client.workspace = true +chirp-workflow.workspace = true rivet-operation.workspace = true chrono = "0.4" http = "0.2" @@ -53,6 +54,7 @@ token-create.workspace = true token-revoke.workspace = true upload-complete.workspace = true upload-get.workspace = true +user.workspace = true user-get.workspace = true user-identity-get.workspace = true user-team-list.workspace = true diff --git a/packages/api/actor/src/auth.rs b/packages/api/actor/src/auth.rs index 506f319ffc..b59d578fd7 100644 --- a/packages/api/actor/src/auth.rs +++ b/packages/api/actor/src/auth.rs @@ -163,9 +163,12 @@ impl Auth { op!([ctx] game_get { game_ids: vec![game_id.into()], }), - op!([ctx] user_team_list { - user_ids: vec![user_ent.user_id.into()], - }), + chirp_workflow::compat::op( + &ctx, + user::ops::team_list::Input { + user_ids: vec![user_ent.user_id.into()], + }, + ), )?; let Some(user) = user_res.users.first() else { bail_with!(TOKEN_REVOKED) @@ -186,8 +189,8 @@ impl Auth { let is_part_of_team = user_teams .teams .iter() - .filter_map(|x| x.team_id) - .any(|x| x.as_uuid() == dev_team_id); + // TODO(ABC): Check uuid + .any(|x| x.team_id == dev_team_id); ensure_with!(is_part_of_team, GROUP_NOT_MEMBER); // Get team diff --git a/packages/api/cloud/Cargo.toml b/packages/api/cloud/Cargo.toml index 1b4748f45f..0840c2ae8e 100644 --- a/packages/api/cloud/Cargo.toml +++ b/packages/api/cloud/Cargo.toml @@ -11,6 +11,7 @@ async-trait = "0.1" base64 = "0.13" bytes = "1.0" chirp-client.workspace = true +chirp-workflow.workspace = true chrono = "0.4" futures-util = "0.3" http = "0.2" @@ -107,6 +108,7 @@ upload-complete.workspace = true upload-file-list.workspace = true upload-get.workspace = true upload-prepare.workspace = true +user.workspace = true user-get.workspace = true user-identity-get.workspace = true user-team-list.workspace = true diff --git a/packages/api/cloud/src/auth.rs b/packages/api/cloud/src/auth.rs index 5b538f4874..a2613b4145 100644 --- a/packages/api/cloud/src/auth.rs +++ b/packages/api/cloud/src/auth.rs @@ -94,16 +94,19 @@ impl Auth { let (user, user_ent) = self.user(ctx).await?; assert::user_registered(ctx, user_ent.user_id).await?; - let team_list_res = op!([ctx] user_team_list { - user_ids: vec![user_ent.user_id.into()], - }) + let team_list_res = chirp_workflow::compat::op( + &ctx, + user::ops::team_list::Input { + user_ids: vec![user_ent.user_id.into()], + }, + ) .await?; let user_teams = unwrap!(team_list_res.users.first()); let user_team_ids = user_teams .teams .iter() - .map(|t| Ok(unwrap_ref!(t.team_id).as_uuid())) + .map(|t| Ok(t.team_id)) .collect::>>()?; let has_teams = team_ids .iter() @@ -271,24 +274,26 @@ impl Auth { let (_, user_ent) = self.user(ctx).await?; // Fetch teams associated with user - let teams_res = op!([ctx] user_team_list { - user_ids: vec![user_ent.user_id.into()], - }) + let teams_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::team_list::Input { + user_ids: vec![user_ent.user_id.into()], + }, + ) .await?; let user = unwrap!(teams_res.users.first()); - let team_ids_proto = user + let team_ids = user .teams .iter() - .filter_map(|t| t.team_id) - .collect::>(); - let team_ids = team_ids_proto - .iter() - .map(common::Uuid::as_uuid) + .map(|t| t.team_id) .collect::>(); // Fetch games associated with teams let games_res = op!([ctx] game_list_for_team { - team_ids: team_ids_proto, + team_ids: team_ids + .iter() + .map(|id| (*id).into()) + .collect::>() }) .await?; diff --git a/packages/api/games/Cargo.toml b/packages/api/games/Cargo.toml index fe585e41af..cb8a0aae77 100644 --- a/packages/api/games/Cargo.toml +++ b/packages/api/games/Cargo.toml @@ -8,6 +8,7 @@ edition.workspace = true [dependencies] api-helper.workspace = true chirp-client.workspace = true +chirp-workflow.workspace = true rivet-operation.workspace = true chrono = "0.4" http = "0.2" @@ -45,6 +46,7 @@ token-revoke.workspace = true token-create.workspace = true upload-complete.workspace = true upload-get.workspace = true +user.workspace = true user-get.workspace = true user-identity-get.workspace = true user-team-list.workspace = true diff --git a/packages/api/games/src/auth.rs b/packages/api/games/src/auth.rs index e593eae80e..4c63ce47e9 100644 --- a/packages/api/games/src/auth.rs +++ b/packages/api/games/src/auth.rs @@ -103,9 +103,12 @@ impl Auth { op!([ctx] game_get { game_ids: vec![game_id.into()], }), - op!([ctx] user_team_list { - user_ids: vec![user_ent.user_id.into()], - }), + chirp_workflow::compat::op( + &ctx, + ::user::ops::team_list::Input { + user_ids: vec![user_ent.user_id.into()], + }, + ) )?; let Some(user) = user_res.users.first() else { bail_with!(TOKEN_REVOKED) @@ -126,8 +129,7 @@ impl Auth { let is_part_of_team = user_teams .teams .iter() - .filter_map(|x| x.team_id) - .any(|x| x.as_uuid() == dev_team_id); + .any(|x| x.team_id == dev_team_id); ensure_with!(is_part_of_team, GROUP_NOT_MEMBER); // Get team diff --git a/packages/api/group/Cargo.toml b/packages/api/group/Cargo.toml index 8ad2bdcc35..0c77f8c12d 100644 --- a/packages/api/group/Cargo.toml +++ b/packages/api/group/Cargo.toml @@ -10,6 +10,7 @@ rivet-convert.workspace = true api-helper.workspace = true async-trait = "0.1" chirp-client.workspace = true +chirp-workflow.workspace = true rivet-operation.workspace = true chrono = "0.4" futures-util = "0.3" @@ -50,6 +51,7 @@ team-user-ban-get.workspace = true team-user-ban-list.workspace = true token-revoke.workspace = true upload-prepare.workspace = true +user.workspace = true user-get.workspace = true user-identity-get.workspace = true user-team-list.workspace = true diff --git a/packages/api/group/src/fetch/group.rs b/packages/api/group/src/fetch/group.rs index 8d879909a4..1069b81106 100644 --- a/packages/api/group/src/fetch/group.rs +++ b/packages/api/group/src/fetch/group.rs @@ -17,9 +17,11 @@ pub async fn summaries( // Fetch team metadata let (user_team_list_res, teams_res, team_member_count_res) = tokio::try_join!( - op!([ctx] user_team_list { - user_ids: vec![current_user_id.into()], - }), + (*ctx).op( + ::user::ops::team_list::Input { + user_ids: vec![current_user_id.into()], + } + ), op!([ctx] team_get { team_ids: group_ids_proto.clone(), }), @@ -34,7 +36,9 @@ pub async fn summaries( .teams .iter() .map(|team| { - let is_current_identity_member = user_teams.iter().any(|t| t.team_id == team.team_id); + let is_current_identity_member = user_teams + .iter() + .any(|t| Some(common::Uuid::from(t.team_id)) == team.team_id); convert::group::summary( ctx.config(), diff --git a/packages/api/group/src/route/groups.rs b/packages/api/group/src/route/groups.rs index 789f477818..a656774ed2 100644 --- a/packages/api/group/src/route/groups.rs +++ b/packages/api/group/src/route/groups.rs @@ -194,16 +194,18 @@ pub async fn members( let (user, user_ent) = ctx.auth().user(ctx.op_ctx()).await?; // Check if user is a member of this team - let team_list_res = op!([ctx] user_team_list { - user_ids: vec![user_ent.user_id.into()], - }) + let team_list_res = (*ctx).op( + ::user::ops::team_list::Input { + user_ids: vec![user_ent.user_id.into()], + } + ) .await?; let user_team = unwrap!(team_list_res.users.first()); let user_team_ids = user_team .teams .iter() - .map(|t| Ok(unwrap_ref!(t.team_id).as_uuid())) + .map(|t| Ok(t.team_id)) .collect::>>()?; let has_team = user_team_ids.iter().any(|team_id| &group_id == team_id); diff --git a/packages/api/portal/Cargo.toml b/packages/api/portal/Cargo.toml index ccc62491fd..f88b323cb2 100644 --- a/packages/api/portal/Cargo.toml +++ b/packages/api/portal/Cargo.toml @@ -10,6 +10,7 @@ rivet-convert.workspace = true api-helper.workspace = true async-trait = "0.1" chirp-client.workspace = true +chirp-workflow.workspace = true rivet-operation.workspace = true chrono = "0.4" futures-util = "0.3" @@ -41,6 +42,7 @@ game-resolve-name-id.workspace = true team-get.workspace = true team-member-count.workspace = true token-revoke.workspace = true +user.workspace = true user-get.workspace = true user-team-list.workspace = true rivet-config.workspace = true diff --git a/packages/api/portal/src/build.rs b/packages/api/portal/src/build.rs index ffe5d7b519..183db79b8e 100644 --- a/packages/api/portal/src/build.rs +++ b/packages/api/portal/src/build.rs @@ -13,9 +13,11 @@ pub async fn group_summaries( ) -> GlobalResult> { // Fetch team metadata let (user_team_list_res, teams_res, team_member_count_res) = tokio::try_join!( - op!([ctx] user_team_list { - user_ids: vec![current_user_id], - }), + (*ctx).op( + ::user::ops::team_list::Input { + user_ids: vec![current_user_id.into()], + } + ), op!([ctx] team_get { team_ids: group_ids.to_vec(), }), @@ -35,7 +37,8 @@ pub async fn group_summaries( let is_current_user_member = unwrap!(user_team_list_res.users.first()) .teams .iter() - .any(|team| team.team_id.as_ref() == Some(group_id)); + // TODO(ABC): check usage + .any(|team| common::Uuid::from(team.team_id) == (*group_id)); let member_count = unwrap!(team_member_count_res .teams .iter() diff --git a/packages/common/convert/Cargo.toml b/packages/common/convert/Cargo.toml index 89f5ac4eb4..de4dc04cc3 100644 --- a/packages/common/convert/Cargo.toml +++ b/packages/common/convert/Cargo.toml @@ -7,6 +7,7 @@ edition.workspace = true [dependencies] chirp-client.workspace = true +chirp-workflow.workspace = true rivet-operation.workspace = true serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -35,6 +36,7 @@ team-member-count.workspace = true team-profile-validate.workspace = true team-validate.workspace = true tier.workspace = true +user.workspace = true user-get.workspace = true user-identity-get.workspace = true user-team-list.workspace = true diff --git a/packages/common/convert/src/convert/identity.rs b/packages/common/convert/src/convert/identity.rs index 1d3f276a16..2e438000d8 100644 --- a/packages/common/convert/src/convert/identity.rs +++ b/packages/common/convert/src/convert/identity.rs @@ -81,11 +81,11 @@ pub fn profile( .user_teams .users .iter() - .find(|u| u.user_id == user.user_id)); + .find(|u| Some(common::Uuid::from(u.user_id)) == user.user_id)); let team_ids = user .teams .iter() - .map(|t| Ok(unwrap!(t.team_id))) + .map(|t| Ok(common::Uuid::from(t.team_id))) .collect::>>()?; pctx.teams_ctx diff --git a/packages/common/convert/src/fetch/group.rs b/packages/common/convert/src/fetch/group.rs index 93111b0ab2..43c90fccfd 100644 --- a/packages/common/convert/src/fetch/group.rs +++ b/packages/common/convert/src/fetch/group.rs @@ -22,9 +22,12 @@ pub async fn summaries( let (user_teams, teams_res, team_member_count_res) = tokio::try_join!( async { if let Some(current_user_id) = current_user_id { - let user_team_list_res = op!([ctx] user_team_list { - user_ids: vec![current_user_id.into()], - }) + let user_team_list_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::team_list::Input { + user_ids: vec![current_user_id.into()], + }, + ) .await?; Ok(unwrap!(user_team_list_res.users.first()).teams.clone()) @@ -44,7 +47,9 @@ pub async fn summaries( .teams .iter() .map(|team| { - let is_current_identity_member = user_teams.iter().any(|t| t.team_id == team.team_id); + let is_current_identity_member = user_teams + .iter() + .any(|t| Some(common::Uuid::from(t.team_id)) == team.team_id); convert::group::summary( ctx.config(), diff --git a/packages/common/convert/src/fetch/identity.rs b/packages/common/convert/src/fetch/identity.rs index 2f92569430..ea26392c01 100644 --- a/packages/common/convert/src/fetch/identity.rs +++ b/packages/common/convert/src/fetch/identity.rs @@ -9,7 +9,7 @@ use crate::convert; #[derive(Debug)] pub struct TeamsCtx { - pub user_teams: user::team_list::Response, + pub user_teams: ::user::ops::team_list::Output, pub teams: Vec, } @@ -114,9 +114,18 @@ pub async fn users( } async fn teams(ctx: &OperationContext<()>, user_ids: Vec) -> GlobalResult { - let user_teams_res = op!([ctx] user_team_list { - user_ids: user_ids, - }) + // let user_teams_res = op!([ctx] user_team_list { + // user_ids: user_ids, + // }) + let user_teams_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::team_list::Input { + user_ids: user_ids + .iter() + .map(|x| (*x).into()) + .collect::>(), + }, + ) .await?; let team_ids = user_teams_res @@ -125,7 +134,7 @@ async fn teams(ctx: &OperationContext<()>, user_ids: Vec) -> Globa .map(|user| { user.teams .iter() - .map(|t| Ok(unwrap!(t.team_id))) + .map(|t| Ok(common::Uuid::from(t.team_id))) .collect::>>() }) .collect::>>()? diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index b3085dc82b..8730591437 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -6,6 +6,7 @@ license.workspace = true edition.workspace = true [dependencies] +serde = { version = "1.0.198", features = ["derive"] } chirp-workflow.workspace = true cluster.workspace = true diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index b081cc6b49..b9b63fd6d9 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -1 +1,2 @@ pub mod resolve_display_name; +pub mod team_list; \ No newline at end of file diff --git a/packages/services/user/src/ops/team_list.rs b/packages/services/user/src/ops/team_list.rs new file mode 100644 index 0000000000..543c1fd729 --- /dev/null +++ b/packages/services/user/src/ops/team_list.rs @@ -0,0 +1,68 @@ +use chirp_workflow::prelude::*; + +#[derive(Debug)] +pub struct Input { + pub user_ids: Vec, +} + +#[derive(Debug)] +pub struct Output { + pub users: Vec, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct UserTeams { + pub user_id: Uuid, + pub teams: Vec, +} + +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct TeamMember { + pub team_id: Uuid, +} + +#[operation] +pub async fn team_list(ctx: &OperationCtx, input: &Input) -> GlobalResult { + + let users = ctx + .cache() + .fetch_all_json("user_team_list", input.user_ids.clone(), { + let ctx = ctx.clone(); + move |mut cache, user_ids| { + let ctx = ctx.clone(); + async move { + let team_members = sql_fetch_all!( + [ctx, (Uuid, Uuid)] + " + SELECT user_id, team_id + FROM db_team.team_members + WHERE user_id = ANY($1) + ", + &user_ids, + ) + .await?; + + for user_id in user_ids { + // Aggregate user teams + let user_teams = UserTeams { + user_id: user_id, + teams: team_members + .iter() + .filter(|(team_user_id, _)| *team_user_id == user_id) + .map(|(_, team_id)| TeamMember { + team_id: *team_id, + }) + .collect(), + }; + + cache.resolve(&user_id.clone(), user_teams); + } + + Ok(cache) + } + } + }) + .await?; + + Ok(Output { users }) +} diff --git a/packages/services/user/worker/Cargo.toml b/packages/services/user/worker/Cargo.toml index 809a6c8254..0b223ffd34 100644 --- a/packages/services/user/worker/Cargo.toml +++ b/packages/services/user/worker/Cargo.toml @@ -8,18 +8,19 @@ edition.workspace = true [dependencies] rivet-convert.workspace = true chirp-client.workspace = true +chirp-workflow.workspace = true chirp-worker.workspace = true chrono = "0.4" lazy_static = "1.4.0" rivet-health-checks.workspace = true rivet-metrics.workspace = true rivet-runtime.workspace = true - game-get.workspace = true game-namespace-get.workspace = true team-get.workspace = true team-member-list.workspace = true upload-list-for-user.workspace = true +user.workspace = true user-get.workspace = true user-identity-delete.workspace = true user-profile-validate.workspace = true diff --git a/packages/services/user/worker/src/workers/delete.rs b/packages/services/user/worker/src/workers/delete.rs index cac285c196..2b323c9830 100644 --- a/packages/services/user/worker/src/workers/delete.rs +++ b/packages/services/user/worker/src/workers/delete.rs @@ -55,16 +55,24 @@ async fn worker(ctx: &OperationContext) -> GlobalRes { tracing::info!(?user_id, "removing teams"); - let user_teams_res = op!([ctx] user_team_list { - user_ids: vec![user_id.into()], - }) + // OLD + // let user_teams_res = op!([ctx] user_team_list { + // user_ids: vec![user_id.into()], + // }) + // .await?; + let user_teams_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::team_list::Input { + user_ids: vec![user_id.into()], + }, + ) .await?; let user_teams = unwrap!(user_teams_res.users.first()); let teams_res = op!([ctx] team_get { team_ids: user_teams.teams .iter() - .map(|member| Ok(unwrap!(member.team_id))) + .map(|member| Ok(member.team_id.into())) .collect::>>()? }) .await?; From ab959b1a69941cfe36a920365715bcdcd241ad16 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:20:33 +0000 Subject: [PATCH 02/11] chore(user/team-list): migrate leftover references --- Cargo.lock | 7 ------- packages/api/actor/Cargo.toml | 1 - packages/api/actor/src/auth.rs | 1 - packages/api/cloud/Cargo.toml | 1 - packages/api/games/Cargo.toml | 1 - packages/api/group/Cargo.toml | 1 - packages/api/portal/Cargo.toml | 1 - packages/api/portal/src/build.rs | 1 - packages/common/convert/Cargo.toml | 1 - packages/common/convert/src/fetch/identity.rs | 3 --- packages/services/user/worker/Cargo.toml | 1 - 11 files changed, 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fae559b2fa..378ad80959 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -317,7 +317,6 @@ dependencies = [ "user", "user-get", "user-identity-get", - "user-team-list", "uuid", ] @@ -518,7 +517,6 @@ dependencies = [ "user-get", "user-identity-create", "user-identity-get", - "user-team-list", "uuid", ] @@ -580,7 +578,6 @@ dependencies = [ "user", "user-get", "user-identity-get", - "user-team-list", "uuid", ] @@ -636,7 +633,6 @@ dependencies = [ "user", "user-get", "user-identity-get", - "user-team-list", "user-token-create", "uuid", ] @@ -957,7 +953,6 @@ dependencies = [ "url", "user", "user-get", - "user-team-list", "user-token-create", "uuid", ] @@ -11773,7 +11768,6 @@ dependencies = [ "user", "user-get", "user-identity-get", - "user-team-list", ] [[package]] @@ -16113,7 +16107,6 @@ dependencies = [ "user-get", "user-identity-delete", "user-profile-validate", - "user-team-list", ] [[package]] diff --git a/packages/api/actor/Cargo.toml b/packages/api/actor/Cargo.toml index c0a80b6f02..d0719fb4fd 100644 --- a/packages/api/actor/Cargo.toml +++ b/packages/api/actor/Cargo.toml @@ -57,7 +57,6 @@ upload-get.workspace = true user.workspace = true user-get.workspace = true user-identity-get.workspace = true -user-team-list.workspace = true [dev-dependencies] rivet-connection.workspace = true diff --git a/packages/api/actor/src/auth.rs b/packages/api/actor/src/auth.rs index b59d578fd7..dde36f13e1 100644 --- a/packages/api/actor/src/auth.rs +++ b/packages/api/actor/src/auth.rs @@ -189,7 +189,6 @@ impl Auth { let is_part_of_team = user_teams .teams .iter() - // TODO(ABC): Check uuid .any(|x| x.team_id == dev_team_id); ensure_with!(is_part_of_team, GROUP_NOT_MEMBER); diff --git a/packages/api/cloud/Cargo.toml b/packages/api/cloud/Cargo.toml index 0840c2ae8e..b690b57e9a 100644 --- a/packages/api/cloud/Cargo.toml +++ b/packages/api/cloud/Cargo.toml @@ -111,7 +111,6 @@ upload-prepare.workspace = true user.workspace = true user-get.workspace = true user-identity-get.workspace = true -user-team-list.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/games/Cargo.toml b/packages/api/games/Cargo.toml index cb8a0aae77..bef16888ab 100644 --- a/packages/api/games/Cargo.toml +++ b/packages/api/games/Cargo.toml @@ -49,7 +49,6 @@ upload-get.workspace = true user.workspace = true user-get.workspace = true user-identity-get.workspace = true -user-team-list.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/group/Cargo.toml b/packages/api/group/Cargo.toml index 0c77f8c12d..8ca60e3284 100644 --- a/packages/api/group/Cargo.toml +++ b/packages/api/group/Cargo.toml @@ -54,7 +54,6 @@ upload-prepare.workspace = true user.workspace = true user-get.workspace = true user-identity-get.workspace = true -user-team-list.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/portal/Cargo.toml b/packages/api/portal/Cargo.toml index f88b323cb2..1944c3b3c8 100644 --- a/packages/api/portal/Cargo.toml +++ b/packages/api/portal/Cargo.toml @@ -44,7 +44,6 @@ team-member-count.workspace = true token-revoke.workspace = true user.workspace = true user-get.workspace = true -user-team-list.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/portal/src/build.rs b/packages/api/portal/src/build.rs index 183db79b8e..bed56ac22b 100644 --- a/packages/api/portal/src/build.rs +++ b/packages/api/portal/src/build.rs @@ -37,7 +37,6 @@ pub async fn group_summaries( let is_current_user_member = unwrap!(user_team_list_res.users.first()) .teams .iter() - // TODO(ABC): check usage .any(|team| common::Uuid::from(team.team_id) == (*group_id)); let member_count = unwrap!(team_member_count_res .teams diff --git a/packages/common/convert/Cargo.toml b/packages/common/convert/Cargo.toml index de4dc04cc3..e78febd606 100644 --- a/packages/common/convert/Cargo.toml +++ b/packages/common/convert/Cargo.toml @@ -39,7 +39,6 @@ tier.workspace = true user.workspace = true user-get.workspace = true user-identity-get.workspace = true -user-team-list.workspace = true rivet-api.workspace = true rivet-group-server.workspace = true diff --git a/packages/common/convert/src/fetch/identity.rs b/packages/common/convert/src/fetch/identity.rs index ea26392c01..3eadde0063 100644 --- a/packages/common/convert/src/fetch/identity.rs +++ b/packages/common/convert/src/fetch/identity.rs @@ -114,9 +114,6 @@ pub async fn users( } async fn teams(ctx: &OperationContext<()>, user_ids: Vec) -> GlobalResult { - // let user_teams_res = op!([ctx] user_team_list { - // user_ids: user_ids, - // }) let user_teams_res = chirp_workflow::compat::op( &ctx, ::user::ops::team_list::Input { diff --git a/packages/services/user/worker/Cargo.toml b/packages/services/user/worker/Cargo.toml index 0b223ffd34..3b756eb5e5 100644 --- a/packages/services/user/worker/Cargo.toml +++ b/packages/services/user/worker/Cargo.toml @@ -24,7 +24,6 @@ user.workspace = true user-get.workspace = true user-identity-delete.workspace = true user-profile-validate.workspace = true -user-team-list.workspace = true rivet-config.workspace = true [dev-dependencies] From 0afa7fd72bc6643388717d3724b235cc8000072b Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Wed, 18 Dec 2024 21:30:33 +0000 Subject: [PATCH 03/11] chore(user/resolve-email): migrate resolve-email op & refs --- Cargo.lock | 2 +- packages/api/auth/Cargo.toml | 3 +- packages/api/auth/src/route/identity.rs | 4 +- packages/services/user/Cargo.toml | 4 ++ packages/services/user/src/ops/mod.rs | 3 +- .../services/user/src/ops/resolve_email.rs | 42 +++++++++++++++++++ packages/services/user/src/ops/team_list.rs | 1 - .../user/worker/src/workers/delete.rs | 5 --- 8 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 packages/services/user/src/ops/resolve_email.rs diff --git a/Cargo.lock b/Cargo.lock index 378ad80959..34b46872d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -364,7 +364,6 @@ dependencies = [ "user-get", "user-identity-create", "user-identity-get", - "user-resolve-email", "user-token-create", "uuid", ] @@ -15922,6 +15921,7 @@ dependencies = [ "rivet-config", "serde", "server-spec", + "sqlx", ] [[package]] diff --git a/packages/api/auth/Cargo.toml b/packages/api/auth/Cargo.toml index 3578124a54..aafbae3ded 100644 --- a/packages/api/auth/Cargo.toml +++ b/packages/api/auth/Cargo.toml @@ -38,11 +38,10 @@ tokio = { version = "1.40" } tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" +user.workspace = true user-get.workspace = true user-identity-create.workspace = true -user-resolve-email.workspace = true user-token-create.workspace = true -user.workspace = true uuid = { version = "1", features = ["v4"] } [dev-dependencies] diff --git a/packages/api/auth/src/route/identity.rs b/packages/api/auth/src/route/identity.rs index 89cca03fad..37b49da1e4 100644 --- a/packages/api/auth/src/route/identity.rs +++ b/packages/api/auth/src/route/identity.rs @@ -97,7 +97,7 @@ pub async fn complete( return Ok(models::AuthIdentityCompleteEmailVerificationResponse { status }); } - let email_res = op!([ctx] user_resolve_email { + let email_res = (*ctx).op(::user::ops::resolve_email::Input { emails: vec![res.email.clone()], }) .await?; @@ -106,7 +106,7 @@ pub async fn complete( if let Some(new_user) = email_res.users.first() { tracing::info!(email = %new_user.email, "resolved email"); - let new_user_id = unwrap_ref!(new_user.user_id).as_uuid(); + let new_user_id = new_user.user_id; tracing::info!(old_user_id = %user_ent.user_id, %new_user_id, "identity found, switching user"); diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index 8730591437..a084d1611b 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -13,3 +13,7 @@ cluster.workspace = true server-spec.workspace = true linode.workspace = true rivet-config.workspace = true + +[dependencies.sqlx] +workspace = true +default-features = false \ No newline at end of file diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index b9b63fd6d9..b2170c6cad 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -1,2 +1,3 @@ pub mod resolve_display_name; -pub mod team_list; \ No newline at end of file +pub mod team_list; +pub mod resolve_email; \ No newline at end of file diff --git a/packages/services/user/src/ops/resolve_email.rs b/packages/services/user/src/ops/resolve_email.rs new file mode 100644 index 0000000000..853e64a94f --- /dev/null +++ b/packages/services/user/src/ops/resolve_email.rs @@ -0,0 +1,42 @@ +use chirp_workflow::prelude::*; + +#[derive(Debug)] +pub struct Input { + pub emails: Vec, +} + +#[derive(Debug)] +pub struct Output { + pub users: Vec, +} + +#[derive(Debug, sqlx::FromRow)] +pub struct User { + pub email: String, + pub user_id: Uuid, +} + +#[operation] +pub async fn resolve_email( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + let users = sql_fetch_all!( + [ctx, User] + " + SELECT email, user_id + FROM db_user_identity.emails + WHERE email = ANY($1) + ", + &input.emails, + ) + .await? + .into_iter() + .map(|row| User { + email: row.email, + user_id: row.user_id, + }) + .collect::>(); + + Ok(Output { users }) +} diff --git a/packages/services/user/src/ops/team_list.rs b/packages/services/user/src/ops/team_list.rs index 543c1fd729..b0e11b90a0 100644 --- a/packages/services/user/src/ops/team_list.rs +++ b/packages/services/user/src/ops/team_list.rs @@ -23,7 +23,6 @@ pub struct TeamMember { #[operation] pub async fn team_list(ctx: &OperationCtx, input: &Input) -> GlobalResult { - let users = ctx .cache() .fetch_all_json("user_team_list", input.user_ids.clone(), { diff --git a/packages/services/user/worker/src/workers/delete.rs b/packages/services/user/worker/src/workers/delete.rs index 2b323c9830..a45bd8f524 100644 --- a/packages/services/user/worker/src/workers/delete.rs +++ b/packages/services/user/worker/src/workers/delete.rs @@ -55,11 +55,6 @@ async fn worker(ctx: &OperationContext) -> GlobalRes { tracing::info!(?user_id, "removing teams"); - // OLD - // let user_teams_res = op!([ctx] user_team_list { - // user_ids: vec![user_id.into()], - // }) - // .await?; let user_teams_res = chirp_workflow::compat::op( &ctx, ::user::ops::team_list::Input { From 6e992770f62961011620f725ddae03534e996436 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:20:37 +0000 Subject: [PATCH 04/11] chore(user/token-create): migrate proto ops & refs --- Cargo.lock | 5 +- packages/api/auth/Cargo.toml | 2 - packages/api/auth/src/route/identity.rs | 6 +- packages/api/auth/src/route/tokens.rs | 13 ++-- packages/api/group/Cargo.toml | 1 - packages/api/group/tests/basic.rs | 17 +++-- packages/api/portal/Cargo.toml | 1 - packages/api/portal/tests/basic.rs | 17 +++-- packages/services/user/Cargo.toml | 2 + packages/services/user/src/ops/mod.rs | 3 +- .../services/user/src/ops/token_create.rs | 68 +++++++++++++++++++ 11 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 packages/services/user/src/ops/token_create.rs diff --git a/Cargo.lock b/Cargo.lock index 34b46872d3..d7a5e6a36e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -364,7 +364,6 @@ dependencies = [ "user-get", "user-identity-create", "user-identity-get", - "user-token-create", "uuid", ] @@ -632,7 +631,6 @@ dependencies = [ "user", "user-get", "user-identity-get", - "user-token-create", "uuid", ] @@ -952,7 +950,6 @@ dependencies = [ "url", "user", "user-get", - "user-token-create", "uuid", ] @@ -15919,9 +15916,11 @@ dependencies = [ "cluster", "linode", "rivet-config", + "rivet-operation", "serde", "server-spec", "sqlx", + "token-create", ] [[package]] diff --git a/packages/api/auth/Cargo.toml b/packages/api/auth/Cargo.toml index aafbae3ded..0ac506ac66 100644 --- a/packages/api/auth/Cargo.toml +++ b/packages/api/auth/Cargo.toml @@ -41,7 +41,6 @@ url = "2.2.2" user.workspace = true user-get.workspace = true user-identity-create.workspace = true -user-token-create.workspace = true uuid = { version = "1", features = ["v4"] } [dev-dependencies] @@ -49,7 +48,6 @@ rivet-auth.workspace = true rivet-connection.workspace = true faker-user.workspace = true -user-token-create.workspace = true debug-email-res.workspace = true user-identity-get.workspace = true diff --git a/packages/api/auth/src/route/identity.rs b/packages/api/auth/src/route/identity.rs index 37b49da1e4..adb526cd60 100644 --- a/packages/api/auth/src/route/identity.rs +++ b/packages/api/auth/src/route/identity.rs @@ -110,9 +110,9 @@ pub async fn complete( tracing::info!(old_user_id = %user_ent.user_id, %new_user_id, "identity found, switching user"); - let token_res = op!([ctx] user_token_create { - user_id: Some(new_user_id.into()), - client: Some(ctx.client_info()), + let token_res = (*ctx).op(::user::ops::token_create::Input { + user_id: new_user_id, + client: ctx.client_info(), }) .await?; diff --git a/packages/api/auth/src/route/tokens.rs b/packages/api/auth/src/route/tokens.rs index 87e58a1f9b..7d6a0fdd73 100644 --- a/packages/api/auth/src/route/tokens.rs +++ b/packages/api/auth/src/route/tokens.rs @@ -11,7 +11,7 @@ use crate::{ utils::{delete_refresh_token_header, refresh_token_header}, }; -// Also see user-token-create/src/main.rs +// Also see user/src/ops/token_create.rs pub const TOKEN_TTL: i64 = util::duration::minutes(15); pub const REFRESH_TOKEN_TTL: i64 = util::duration::days(90); @@ -205,10 +205,13 @@ async fn fallback_user( }; // Generate token - let token_res = op!([ctx] user_token_create { - user_id: Some(user_id.into()), - client: Some(client_info), - }) + let token_res = chirp_workflow::compat::op( + ctx, + ::user::ops::token_create::Input { + user_id: user_id, + client: client_info, + }, + ) .await?; Ok((token_res.token.clone(), token_res.refresh_token)) diff --git a/packages/api/group/Cargo.toml b/packages/api/group/Cargo.toml index 8ca60e3284..bf084cc0e5 100644 --- a/packages/api/group/Cargo.toml +++ b/packages/api/group/Cargo.toml @@ -63,4 +63,3 @@ rivet-group.workspace = true rand = "0.8" faker-user.workspace = true -user-token-create.workspace = true diff --git a/packages/api/group/tests/basic.rs b/packages/api/group/tests/basic.rs index 778d75d050..d280ddc85c 100644 --- a/packages/api/group/tests/basic.rs +++ b/packages/api/group/tests/basic.rs @@ -59,13 +59,16 @@ impl Ctx { let user_res = op!([ctx] faker_user {}).await.unwrap(); let user_id = user_res.user_id.as_ref().unwrap().as_uuid(); - let token_res = op!([ctx] user_token_create { - user_id: user_res.user_id, - client: Some(backend::net::ClientInfo { - user_agent: Some(USER_AGENT.into()), - remote_address: Some(socket_addr().to_string()), - }) - }) + let token_res = chirp_workflow::compat::op( + &ctx, + user::ops::token_create::get::Input { + user_id: user_id, + client: backend::net::ClientInfo { + user_agent: Some(USER_AGENT.into()), + remote_address: Some(socket_addr().to_string()), + } + } + ) .await .unwrap(); diff --git a/packages/api/portal/Cargo.toml b/packages/api/portal/Cargo.toml index 1944c3b3c8..a85f597129 100644 --- a/packages/api/portal/Cargo.toml +++ b/packages/api/portal/Cargo.toml @@ -53,4 +53,3 @@ rivet-portal.workspace = true regex = "1.4" faker-user.workspace = true -user-token-create.workspace = true diff --git a/packages/api/portal/tests/basic.rs b/packages/api/portal/tests/basic.rs index f8657fc082..80e1c8e792 100644 --- a/packages/api/portal/tests/basic.rs +++ b/packages/api/portal/tests/basic.rs @@ -58,13 +58,16 @@ impl Ctx { let user_res = op!([ctx] faker_user {}).await.unwrap(); let user_id = user_res.user_id.as_ref().unwrap().as_uuid(); - let token_res = op!([ctx] user_token_create { - user_id: user_res.user_id, - client: Some(backend::net::ClientInfo { - user_agent: Some(USER_AGENT.into()), - remote_address: Some(socket_addr().to_string()), - }) - }) + let token_res = chirp_workflow::compat::op( + &ctx, + user::ops::token_create::get::Input { + user_id: user_id, + client: backend::net::ClientInfo { + user_agent: Some(USER_AGENT.into()), + remote_address: Some(socket_addr().to_string()), + } + } + ) .await .unwrap(); diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index a084d1611b..a29e086c95 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -13,6 +13,8 @@ cluster.workspace = true server-spec.workspace = true linode.workspace = true rivet-config.workspace = true +rivet-operation.workspace = true +token-create.workspace = true [dependencies.sqlx] workspace = true diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index b2170c6cad..9ac3acbd34 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -1,3 +1,4 @@ pub mod resolve_display_name; pub mod team_list; -pub mod resolve_email; \ No newline at end of file +pub mod resolve_email; +pub mod token_create; \ No newline at end of file diff --git a/packages/services/user/src/ops/token_create.rs b/packages/services/user/src/ops/token_create.rs new file mode 100644 index 0000000000..535650c932 --- /dev/null +++ b/packages/services/user/src/ops/token_create.rs @@ -0,0 +1,68 @@ +use chirp_workflow::prelude::*; +use proto::backend::{self, pkg::*}; +use rivet_operation::prelude::proto; + +// Also see api/auth/src/route/tokens.rs +pub const TOKEN_TTL: i64 = util::duration::minutes(15); +pub const REFRESH_TOKEN_TTL: i64 = util::duration::days(90); + +#[derive(Debug)] +pub struct Input { + pub user_id: Uuid, + pub client: backend::net::ClientInfo, +} + +#[derive(Debug)] +pub struct Output { + pub token: String, + pub refresh_token: String +} + + +#[operation] +pub async fn token_create( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + let user_id = input.user_id; + + let token_res = op!([ctx] token_create { + token_config: Some(token::create::request::TokenConfig { + ttl: TOKEN_TTL, + }), + refresh_token_config: Some(token::create::request::TokenConfig { + ttl: REFRESH_TOKEN_TTL, + }), + issuer: Self::NAME.to_owned(), + client: Some(input.client.clone()), + kind: Some(token::create::request::Kind::New( + token::create::request::KindNew { + entitlements: vec![proto::claims::Entitlement { + kind: Some(proto::claims::entitlement::Kind::User(proto::claims::entitlement::User { + user_id: Some(user_id.into()), + })), + }], + }, + )), + label: Some("usr".into()), + ..Default::default() + }) + .await?; + + let token = unwrap_ref!(token_res.token); + let refresh_token = unwrap_ref!(token_res.refresh_token); + let token_session_id = unwrap_ref!(token_res.session_id).as_uuid(); + + sql_execute!( + [ctx] + "INSERT INTO db_user.user_tokens (user_id, token_session_id) VALUES ($1, $2)", + user_id, + token_session_id, + ) + .await?; + + Ok(Output { + token: token.token.clone(), + refresh_token: refresh_token.token.clone(), + }) +} From b643aa75cb5311cd258993ebaaf830d29f763966 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:37:14 +0000 Subject: [PATCH 05/11] chore(user/profile-validate): migrate ops & refs --- Cargo.lock | 5 +- packages/api/identity/Cargo.toml | 3 +- packages/api/identity/src/route/identities.rs | 11 +- packages/services/user/Cargo.toml | 1 + packages/services/user/src/ops/mod.rs | 3 +- .../services/user/src/ops/profile_validate.rs | 109 ++++++++++++++++++ packages/services/user/worker/Cargo.toml | 1 - .../user/worker/src/workers/profile_set.rs | 15 ++- 8 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 packages/services/user/src/ops/profile_validate.rs diff --git a/Cargo.lock b/Cargo.lock index d7a5e6a36e..f11f3a3d4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -697,6 +697,7 @@ dependencies = [ "cdn-namespace-domain-create", "cdn-namespace-get", "chirp-client", + "chirp-workflow", "cloud-namespace-token-development-create", "faker-build", "faker-game", @@ -744,11 +745,11 @@ dependencies = [ "tracing-subscriber", "upload-prepare", "url", + "user", "user-avatar-upload-complete", "user-get", "user-identity-get", "user-pending-delete-toggle", - "user-profile-validate", "uuid", ] @@ -15921,6 +15922,7 @@ dependencies = [ "server-spec", "sqlx", "token-create", + "user-get", ] [[package]] @@ -16105,7 +16107,6 @@ dependencies = [ "user", "user-get", "user-identity-delete", - "user-profile-validate", ] [[package]] diff --git a/packages/api/identity/Cargo.toml b/packages/api/identity/Cargo.toml index be42386f2a..2eb831b95a 100644 --- a/packages/api/identity/Cargo.toml +++ b/packages/api/identity/Cargo.toml @@ -9,6 +9,7 @@ edition.workspace = true rivet-convert.workspace = true api-helper.workspace = true async-trait = "0.1" +chirp-workflow.workspace = true chirp-client.workspace = true rivet-operation.workspace = true futures-util = "0.3" @@ -50,11 +51,11 @@ token-create.workspace = true token-get.workspace = true token-revoke.workspace = true upload-prepare.workspace = true +user.workspace = true user-avatar-upload-complete.workspace = true user-get.workspace = true user-identity-get.workspace = true user-pending-delete-toggle.workspace = true -user-profile-validate.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/identity/src/route/identities.rs b/packages/api/identity/src/route/identities.rs index ddecbb5ec2..4ce3e24faf 100644 --- a/packages/api/identity/src/route/identities.rs +++ b/packages/api/identity/src/route/identities.rs @@ -217,13 +217,12 @@ pub async fn validate_profile( "invalid parameter account_number`" ); - let res = op!([ctx] user_profile_validate { - user_id: Some(user_ent.user_id.into()), + let res = (*ctx).op(::user::ops::profile_validate::Input { + user_id: user_ent.user_id, display_name: body.display_name.clone(), - account_number: - body.account_number - .map(|n| n.api_try_into()) - .transpose()?, + account_number: body.account_number + .map(|n| n.api_try_into()) + .transpose()?, bio: body.bio.clone(), }) .await?; diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index a29e086c95..ee8c28bc8b 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -15,6 +15,7 @@ linode.workspace = true rivet-config.workspace = true rivet-operation.workspace = true token-create.workspace = true +user-get.workspace = true [dependencies.sqlx] workspace = true diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index 9ac3acbd34..99f2a9af61 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -1,4 +1,5 @@ +pub mod profile_validate; pub mod resolve_display_name; -pub mod team_list; pub mod resolve_email; +pub mod team_list; pub mod token_create; \ No newline at end of file diff --git a/packages/services/user/src/ops/profile_validate.rs b/packages/services/user/src/ops/profile_validate.rs new file mode 100644 index 0000000000..43524161d4 --- /dev/null +++ b/packages/services/user/src/ops/profile_validate.rs @@ -0,0 +1,109 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::common; + +#[derive(Debug)] +pub struct Input { + pub user_id: Uuid, + pub display_name: Option, + pub account_number: Option, + pub bio: Option, +} + +#[derive(Debug)] +pub struct Output { + pub errors: Vec, +} + + +#[operation] +pub async fn profile_validate( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + let mut errors = Vec::new(); + + // Validate display name + if let Some(display_name) = &input.display_name { + if display_name.is_empty() { + errors.push(util::err_path!["display-name", "too-short"]); + } else if display_name.len() > util::check::MAX_DISPLAY_NAME_LEN { + errors.push(util::err_path!["display-name", "too-long"]); + } + + if !util::check::display_name(display_name) { + errors.push(util::err_path!["display-name", "invalid"]); + } + } + + // Validate account number + if let Some(account_number) = &input.account_number { + if *account_number < 1 || *account_number > 9999 { + errors.push(util::err_path!["account-number-invalid"]); + } + } + + // Validate biography + if let Some(bio) = &input.bio { + if bio.len() > util::check::MAX_BIOGRAPHY_LEN { + errors.push(util::err_path!["bio", "too-long"]); + } + + if !util::check::biography(bio) { + errors.push(util::err_path!["bio", "invalid"]); + } + } + + // Only validate handle uniqueness if at least one of the two handle components is given + if input.display_name.is_some() || input.account_number.is_some() { + // If either the display name or account number are missing, fetch them from the given user + let (display_name, account_number) = + if input.display_name.is_none() || input.account_number.is_none() { + let users_res = op!([ctx] user_get { + user_ids: vec![input.user_id.into()], + }) + .await?; + + let user = users_res.users.first(); + let user = unwrap_ref!(user, "user not found"); + + ( + input.display_name + .clone() + .unwrap_or(user.display_name.clone()), + input.account_number.unwrap_or(user.account_number), + ) + } else { + ( + unwrap_ref!(input.display_name).clone(), + *unwrap_ref!(input.account_number), + ) + }; + + // Find user by handle + let (user_exists,) = sql_fetch_one!( + [ctx, (bool,)] + " + SELECT EXISTS ( + SELECT 1 + FROM db_user.users + WHERE display_name = $1 and account_number = $2 + ) + ", + display_name, + account_number as i64, + ) + .await?; + + // Validate handle uniqueness + if user_exists { + errors.push(util::err_path!["handle-not-unique"]); + } + } + + Ok(Output { + errors: errors + .into_iter() + .map(|path| common::ValidationError { path }) + .collect::>(), + }) +} \ No newline at end of file diff --git a/packages/services/user/worker/Cargo.toml b/packages/services/user/worker/Cargo.toml index 3b756eb5e5..d548f19529 100644 --- a/packages/services/user/worker/Cargo.toml +++ b/packages/services/user/worker/Cargo.toml @@ -23,7 +23,6 @@ upload-list-for-user.workspace = true user.workspace = true user-get.workspace = true user-identity-delete.workspace = true -user-profile-validate.workspace = true rivet-config.workspace = true [dev-dependencies] diff --git a/packages/services/user/worker/src/workers/profile_set.rs b/packages/services/user/worker/src/workers/profile_set.rs index d2d64b0ced..14017206ca 100644 --- a/packages/services/user/worker/src/workers/profile_set.rs +++ b/packages/services/user/worker/src/workers/profile_set.rs @@ -29,12 +29,15 @@ async fn worker(ctx: &OperationContext) -> Glob ensure!(!query_components.is_empty()); // Validate profile - let validation_res = op!([ctx] user_profile_validate { - user_id: body.user_id, - display_name: display_name.clone(), - account_number: *account_number, - bio: bio.clone() - }) + let validation_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::profile_validate::Input { + user_id: user_id.as_uuid(), + display_name: display_name.clone(), + account_number: *account_number, + bio: bio.clone() + }, + ) .await?; if !validation_res.errors.is_empty() { tracing::warn!(errors = ?validation_res.errors, "validation errors"); From c6408c7c6a20e72187422c2a2034c409649d6732 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:03:34 +0000 Subject: [PATCH 06/11] chore(users/pending-delete-toggle): migrate proto ops & refs --- Cargo.lock | 2 +- packages/api/identity/Cargo.toml | 1 - packages/api/identity/src/route/identities.rs | 8 ++-- packages/services/user/Cargo.toml | 1 + packages/services/user/src/ops/mod.rs | 1 + .../user/src/ops/pending_delete_toggle.rs | 47 +++++++++++++++++++ 6 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 packages/services/user/src/ops/pending_delete_toggle.rs diff --git a/Cargo.lock b/Cargo.lock index f11f3a3d4c..cac0b4b307 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -749,7 +749,6 @@ dependencies = [ "user-avatar-upload-complete", "user-get", "user-identity-get", - "user-pending-delete-toggle", "uuid", ] @@ -15923,6 +15922,7 @@ dependencies = [ "sqlx", "token-create", "user-get", + "user-identity-get", ] [[package]] diff --git a/packages/api/identity/Cargo.toml b/packages/api/identity/Cargo.toml index 2eb831b95a..bc35235217 100644 --- a/packages/api/identity/Cargo.toml +++ b/packages/api/identity/Cargo.toml @@ -55,7 +55,6 @@ user.workspace = true user-avatar-upload-complete.workspace = true user-get.workspace = true user-identity-get.workspace = true -user-pending-delete-toggle.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/identity/src/route/identities.rs b/packages/api/identity/src/route/identities.rs index 4ce3e24faf..886b9af809 100644 --- a/packages/api/identity/src/route/identities.rs +++ b/packages/api/identity/src/route/identities.rs @@ -306,8 +306,8 @@ pub async fn mark_deletion( ) -> GlobalResult { let user_ent = ctx.auth().user(ctx.op_ctx()).await?; - op!([ctx] user_pending_delete_toggle { - user_id: Some(user_ent.user_id.into()), + (*ctx).op(::user::ops::pending_delete_toggle::Input { + user_id: user_ent.user_id, active: true, }) .await?; @@ -319,8 +319,8 @@ pub async fn mark_deletion( pub async fn unmark_deletion(ctx: Ctx) -> GlobalResult { let user_ent = ctx.auth().user(ctx.op_ctx()).await?; - op!([ctx] user_pending_delete_toggle { - user_id: Some(user_ent.user_id.into()), + (*ctx).op(::user::ops::pending_delete_toggle::Input { + user_id: user_ent.user_id, active: false, }) .await?; diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index ee8c28bc8b..656d03194b 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -16,6 +16,7 @@ rivet-config.workspace = true rivet-operation.workspace = true token-create.workspace = true user-get.workspace = true +user-identity-get.workspace = true [dependencies.sqlx] workspace = true diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index 99f2a9af61..ce39cfd97d 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -1,3 +1,4 @@ +pub mod pending_delete_toggle; pub mod profile_validate; pub mod resolve_display_name; pub mod resolve_email; diff --git a/packages/services/user/src/ops/pending_delete_toggle.rs b/packages/services/user/src/ops/pending_delete_toggle.rs new file mode 100644 index 0000000000..190cf1a6ad --- /dev/null +++ b/packages/services/user/src/ops/pending_delete_toggle.rs @@ -0,0 +1,47 @@ +use chirp_workflow::prelude::*; +use proto::backend::{self, pkg::*}; +use rivet_operation::prelude::proto; + +#[derive(Debug)] +pub struct Input { + pub user_id: Uuid, + pub active: bool +} + +#[derive(Debug)] +pub struct Output { +} + + +#[operation] +pub async fn pending_delete_toggle( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + let user_id = input.user_id; + + // Verify the user is registered + let identity = op!([ctx] user_identity_get { + user_ids: vec![user_id.into()], + }) + .await?; + let identities = &unwrap_ref!(identity.users.first()).identities; + ensure_with!(!identities.is_empty(), IDENTITY_NOT_REGISTERED); + + sql_execute!( + [ctx] + "UPDATE db_user.users SET delete_request_ts = $2 WHERE user_id = $1", + user_id, + input.active.then(util::timestamp::now), + ) + .await?; + + ctx.cache().purge("user", [user_id]).await?; + + msg!([ctx] user::msg::update(user_id) { + user_id: Some(user_id.into()), + }) + .await?; + + Ok(Output {}) +} \ No newline at end of file From daedb9f4d1d51eb2bee0b660d612e5d55534a019 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Thu, 19 Dec 2024 19:16:13 +0000 Subject: [PATCH 07/11] chore(users/get): migrate old proto and refs --- Cargo.lock | 16 +- packages/api/actor/Cargo.toml | 1 - packages/api/actor/src/auth.rs | 11 +- packages/api/auth/Cargo.toml | 1 - packages/api/auth/src/auth.rs | 9 +- packages/api/auth/src/route/tokens.rs | 4 +- packages/api/cloud/Cargo.toml | 1 - packages/api/cloud/src/auth.rs | 9 +- packages/api/games/Cargo.toml | 1 - packages/api/games/src/auth.rs | 9 +- packages/api/group/Cargo.toml | 1 - packages/api/group/src/auth.rs | 18 ++- packages/api/group/src/fetch/identity.rs | 6 +- packages/api/group/src/route/groups.rs | 24 ++- packages/api/identity/Cargo.toml | 1 - packages/api/identity/src/auth.rs | 18 ++- packages/api/portal/Cargo.toml | 1 - packages/api/portal/src/auth.rs | 18 ++- packages/common/convert/Cargo.toml | 1 - .../common/convert/src/convert/identity.rs | 2 +- packages/common/convert/src/fetch/identity.rs | 35 ++--- packages/services/faker/ops/user/Cargo.toml | 4 +- .../faker/ops/user/tests/integration.rs | 4 +- packages/services/user/Cargo.toml | 2 + .../user/ops/profile-validate/Cargo.toml | 3 +- .../user/ops/profile-validate/src/lib.rs | 9 +- packages/services/user/src/ops/get.rs | 140 ++++++++++++++++++ packages/services/user/src/ops/mod.rs | 1 + .../user/src/ops/pending_delete_toggle.rs | 2 +- .../services/user/src/ops/profile_validate.rs | 4 +- 30 files changed, 265 insertions(+), 91 deletions(-) create mode 100644 packages/services/user/src/ops/get.rs diff --git a/Cargo.lock b/Cargo.lock index cac0b4b307..22c4d877f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,7 +315,6 @@ dependencies = [ "upload-get", "url", "user", - "user-get", "user-identity-get", "uuid", ] @@ -361,7 +360,6 @@ dependencies = [ "tracing-subscriber", "url", "user", - "user-get", "user-identity-create", "user-identity-get", "uuid", @@ -512,7 +510,6 @@ dependencies = [ "upload-prepare", "url", "user", - "user-get", "user-identity-create", "user-identity-get", "uuid", @@ -574,7 +571,6 @@ dependencies = [ "upload-get", "url", "user", - "user-get", "user-identity-get", "uuid", ] @@ -629,7 +625,6 @@ dependencies = [ "upload-prepare", "url", "user", - "user-get", "user-identity-get", "uuid", ] @@ -747,7 +742,6 @@ dependencies = [ "url", "user", "user-avatar-upload-complete", - "user-get", "user-identity-get", "uuid", ] @@ -949,7 +943,6 @@ dependencies = [ "tracing-subscriber", "url", "user", - "user-get", "uuid", ] @@ -5900,9 +5893,10 @@ version = "24.6.2-rc.1" dependencies = [ "chirp-client", "chirp-worker", + "chirp-workflow", "prost 0.10.4", "rivet-operation", - "user-get", + "user", ] [[package]] @@ -11762,7 +11756,6 @@ dependencies = [ "tier", "types-proto", "user", - "user-get", "user-identity-get", ] @@ -15921,6 +15914,8 @@ dependencies = [ "server-spec", "sqlx", "token-create", + "upload-file-list", + "upload-get", "user-get", "user-identity-get", ] @@ -16038,11 +16033,12 @@ version = "24.6.2-rc.1" dependencies = [ "chirp-client", "chirp-worker", + "chirp-workflow", "faker-user", "prost 0.10.4", "rivet-operation", "sqlx", - "user-get", + "user", ] [[package]] diff --git a/packages/api/actor/Cargo.toml b/packages/api/actor/Cargo.toml index d0719fb4fd..98cfab5fbf 100644 --- a/packages/api/actor/Cargo.toml +++ b/packages/api/actor/Cargo.toml @@ -55,7 +55,6 @@ token-revoke.workspace = true upload-complete.workspace = true upload-get.workspace = true user.workspace = true -user-get.workspace = true user-identity-get.workspace = true [dev-dependencies] diff --git a/packages/api/actor/src/auth.rs b/packages/api/actor/src/auth.rs index dde36f13e1..fc38a9cea4 100644 --- a/packages/api/actor/src/auth.rs +++ b/packages/api/actor/src/auth.rs @@ -157,16 +157,19 @@ impl Auth { } else if let Ok(user_ent) = claims.as_user() { // Get the user let (user_res, game_res, team_list_res) = tokio::try_join!( - op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], - }), + chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ), op!([ctx] game_get { game_ids: vec![game_id.into()], }), chirp_workflow::compat::op( &ctx, user::ops::team_list::Input { - user_ids: vec![user_ent.user_id.into()], + user_ids: vec![user_ent.user_id], }, ), )?; diff --git a/packages/api/auth/Cargo.toml b/packages/api/auth/Cargo.toml index 0ac506ac66..bb48286e26 100644 --- a/packages/api/auth/Cargo.toml +++ b/packages/api/auth/Cargo.toml @@ -39,7 +39,6 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" user.workspace = true -user-get.workspace = true user-identity-create.workspace = true uuid = { version = "1", features = ["v4"] } diff --git a/packages/api/auth/src/auth.rs b/packages/api/auth/src/auth.rs index 30225b8df0..c82045d618 100644 --- a/packages/api/auth/src/auth.rs +++ b/packages/api/auth/src/auth.rs @@ -51,9 +51,12 @@ impl Auth { let claims = self.claims()?; let user_ent = claims.as_user()?; - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let Some(user) = user_res.users.first() else { bail_with!(TOKEN_REVOKED) diff --git a/packages/api/auth/src/route/tokens.rs b/packages/api/auth/src/route/tokens.rs index 7d6a0fdd73..68a9dc0589 100644 --- a/packages/api/auth/src/route/tokens.rs +++ b/packages/api/auth/src/route/tokens.rs @@ -137,8 +137,8 @@ pub async fn identity( // Verify user is not deleted if has_refresh_token { - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], + let user_res = (*ctx).op(::user::ops::get::Input { + user_ids: vec![user_ent.user_id], }) .await?; let user = unwrap!(user_res.users.first()); diff --git a/packages/api/cloud/Cargo.toml b/packages/api/cloud/Cargo.toml index b690b57e9a..d102043a32 100644 --- a/packages/api/cloud/Cargo.toml +++ b/packages/api/cloud/Cargo.toml @@ -109,7 +109,6 @@ upload-file-list.workspace = true upload-get.workspace = true upload-prepare.workspace = true user.workspace = true -user-get.workspace = true user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/cloud/src/auth.rs b/packages/api/cloud/src/auth.rs index a2613b4145..eb836c93a7 100644 --- a/packages/api/cloud/src/auth.rs +++ b/packages/api/cloud/src/auth.rs @@ -60,9 +60,12 @@ impl Auth { let claims = self.claims()?; let user_ent = claims.as_user()?; - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let Some(user) = user_res.users.first() else { bail_with!(TOKEN_REVOKED) diff --git a/packages/api/games/Cargo.toml b/packages/api/games/Cargo.toml index bef16888ab..77a274cdf1 100644 --- a/packages/api/games/Cargo.toml +++ b/packages/api/games/Cargo.toml @@ -47,7 +47,6 @@ token-create.workspace = true upload-complete.workspace = true upload-get.workspace = true user.workspace = true -user-get.workspace = true user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/games/src/auth.rs b/packages/api/games/src/auth.rs index 4c63ce47e9..aeef00de9e 100644 --- a/packages/api/games/src/auth.rs +++ b/packages/api/games/src/auth.rs @@ -97,9 +97,12 @@ impl Auth { } else if let Ok(user_ent) = claims.as_user() { // Get the user let (user_res, game_res, team_list_res) = tokio::try_join!( - op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], - }), + chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ), op!([ctx] game_get { game_ids: vec![game_id.into()], }), diff --git a/packages/api/group/Cargo.toml b/packages/api/group/Cargo.toml index bf084cc0e5..c4f385a6b2 100644 --- a/packages/api/group/Cargo.toml +++ b/packages/api/group/Cargo.toml @@ -52,7 +52,6 @@ team-user-ban-list.workspace = true token-revoke.workspace = true upload-prepare.workspace = true user.workspace = true -user-get.workspace = true user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/group/src/auth.rs b/packages/api/group/src/auth.rs index 83416b5431..2c17b3d507 100644 --- a/packages/api/group/src/auth.rs +++ b/packages/api/group/src/auth.rs @@ -56,9 +56,12 @@ impl Auth { let claims = self.claims()?; let user_ent = claims.as_user()?; - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let Some(user) = user_res.users.first() else { bail_with!(TOKEN_REVOKED) @@ -86,9 +89,12 @@ impl Auth { let (_, user_ent) = self.user(ctx).await?; // Get user - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()] - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let user = unwrap!(user_res.users.first(), "user not found"); diff --git a/packages/api/group/src/fetch/identity.rs b/packages/api/group/src/fetch/identity.rs index 01e4a74714..0327e37c91 100644 --- a/packages/api/group/src/fetch/identity.rs +++ b/packages/api/group/src/fetch/identity.rs @@ -9,9 +9,9 @@ use crate::{auth::Auth, convert}; pub async fn users( ctx: &Ctx, - user_ids: Vec, -) -> GlobalResult { - op!([ctx] user_get { + user_ids: Vec, +) -> GlobalResult<::user::ops::get::Output> { + (*ctx).op(::user::ops::get::Input { user_ids: user_ids, }) .await diff --git a/packages/api/group/src/route/groups.rs b/packages/api/group/src/route/groups.rs index a656774ed2..09704c25a5 100644 --- a/packages/api/group/src/route/groups.rs +++ b/packages/api/group/src/route/groups.rs @@ -287,7 +287,13 @@ pub async fn members( // NOTE: We don't use fetch::identities::handles here because the end model is `GroupMember` not `IdentityHandle` // Fetch team member and join request data - let users = fetch::identity::users(&ctx, user_ids.clone()).await?; + let users = fetch::identity::users( + &ctx, + user_ids + .iter() + .map(|u| u.as_uuid()) + .collect::>() + ).await?; let raw_user_ent_id = Into::::into(user_ent.user_id); let members = users @@ -424,7 +430,13 @@ pub async fn join_requests( // NOTE: We don't use fetch::identities::handles here because the end model is `GroupMember` not // `IdentityHandle` // Fetch team member and join request data - let users = fetch::identity::users(&ctx, user_ids.clone()).await?; + let users = fetch::identity::users( + &ctx, + user_ids + .iter() + .map(|u| u.as_uuid()) + .collect::>() + ).await?; let raw_user_ent_id = Into::::into(user_ent.user_id); let join_requests = users @@ -1248,7 +1260,13 @@ pub async fn bans( // NOTE: We don't use fetch::identities::handles here because the end model is `BannedIdentity` not // `IdentityHandle` // Fetch team member and ban data - let users = fetch::identity::users(&ctx, user_ids.clone()).await?; + let users = fetch::identity::users( + &ctx, + user_ids + .iter() + .map(|u| u.as_uuid()) + .collect::>() + ).await?; let raw_user_ent_id = Into::::into(user_ent.user_id); let banned_identities = users diff --git a/packages/api/identity/Cargo.toml b/packages/api/identity/Cargo.toml index bc35235217..d4c437e007 100644 --- a/packages/api/identity/Cargo.toml +++ b/packages/api/identity/Cargo.toml @@ -53,7 +53,6 @@ token-revoke.workspace = true upload-prepare.workspace = true user.workspace = true user-avatar-upload-complete.workspace = true -user-get.workspace = true user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/identity/src/auth.rs b/packages/api/identity/src/auth.rs index 507117cd63..62308c24d6 100644 --- a/packages/api/identity/src/auth.rs +++ b/packages/api/identity/src/auth.rs @@ -116,9 +116,12 @@ impl Auth { let claims = self.claims()?; let user_ent = claims.as_user()?; - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let Some(user) = user_res.users.first() else { bail_with!(TOKEN_REVOKED) @@ -143,9 +146,12 @@ impl Auth { let user_ent = self.user(ctx).await?; // Get user - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()] - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let user = unwrap!(user_res.users.first(), "user not found"); diff --git a/packages/api/portal/Cargo.toml b/packages/api/portal/Cargo.toml index a85f597129..2559c9838d 100644 --- a/packages/api/portal/Cargo.toml +++ b/packages/api/portal/Cargo.toml @@ -43,7 +43,6 @@ team-get.workspace = true team-member-count.workspace = true token-revoke.workspace = true user.workspace = true -user-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/portal/src/auth.rs b/packages/api/portal/src/auth.rs index b52f74a370..84ff88dddf 100644 --- a/packages/api/portal/src/auth.rs +++ b/packages/api/portal/src/auth.rs @@ -53,9 +53,12 @@ impl Auth { let claims = self.claims()?; let user_ent = claims.as_user()?; - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()], - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let Some(user) = user_res.users.first() else { bail_with!(TOKEN_REVOKED) @@ -80,9 +83,12 @@ impl Auth { let user_ent = self.user(ctx).await?; // Get user - let user_res = op!([ctx] user_get { - user_ids: vec![user_ent.user_id.into()] - }) + let user_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![user_ent.user_id], + }, + ) .await?; let user = unwrap!(user_res.users.first(), "user not found"); diff --git a/packages/common/convert/Cargo.toml b/packages/common/convert/Cargo.toml index e78febd606..dd47afa125 100644 --- a/packages/common/convert/Cargo.toml +++ b/packages/common/convert/Cargo.toml @@ -37,7 +37,6 @@ team-profile-validate.workspace = true team-validate.workspace = true tier.workspace = true user.workspace = true -user-get.workspace = true user-identity-get.workspace = true rivet-api.workspace = true diff --git a/packages/common/convert/src/convert/identity.rs b/packages/common/convert/src/convert/identity.rs index 2e438000d8..e5c96f0268 100644 --- a/packages/common/convert/src/convert/identity.rs +++ b/packages/common/convert/src/convert/identity.rs @@ -26,7 +26,7 @@ pub fn handle( pub fn summary( config: &rivet_config::Config, - current_user_id: Uuid, + _current_user_id: Uuid, user: &backend::user::User, ) -> GlobalResult { let user_id_proto = unwrap!(user.user_id); diff --git a/packages/common/convert/src/fetch/identity.rs b/packages/common/convert/src/fetch/identity.rs index 3eadde0063..e425de01c0 100644 --- a/packages/common/convert/src/fetch/identity.rs +++ b/packages/common/convert/src/fetch/identity.rs @@ -16,18 +16,12 @@ pub struct TeamsCtx { pub async fn handles( ctx: &OperationContext<()>, current_user_id: Uuid, - raw_user_ids: Vec, + user_ids: Vec, ) -> GlobalResult> { - if raw_user_ids.is_empty() { + if user_ids.is_empty() { return Ok(Vec::new()); } - let user_ids = raw_user_ids - .clone() - .into_iter() - .map(Into::into) - .collect::>(); - let users = users(ctx, user_ids.clone()).await?; // Convert all data @@ -41,18 +35,12 @@ pub async fn handles( pub async fn summaries( ctx: &OperationContext<()>, current_user_id: Uuid, - raw_user_ids: Vec, + user_ids: Vec, ) -> GlobalResult> { - if raw_user_ids.is_empty() { + if user_ids.is_empty() { return Ok(Vec::new()); } - let user_ids = raw_user_ids - .clone() - .into_iter() - .map(Into::into) - .collect::>(); - let users = users(ctx, user_ids.clone()).await?; // Convert all data @@ -79,7 +67,7 @@ pub async fn profiles( .collect::>(); let (users, teams_ctx, linked_accounts) = tokio::try_join!( - users(ctx, user_ids.clone()), + users(ctx, raw_user_ids.clone()), teams(ctx, user_ids.clone()), linked_accounts(ctx, user_ids.clone()), )?; @@ -105,11 +93,14 @@ pub async fn profiles( pub async fn users( ctx: &OperationContext<()>, - user_ids: Vec, -) -> GlobalResult { - op!([ctx] user_get { - user_ids: user_ids, - }) + user_ids: Vec, +) -> GlobalResult<::user::ops::get::Output> { + chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: user_ids, + }, + ) .await } diff --git a/packages/services/faker/ops/user/Cargo.toml b/packages/services/faker/ops/user/Cargo.toml index 67a500e360..9043aa7d3e 100644 --- a/packages/services/faker/ops/user/Cargo.toml +++ b/packages/services/faker/ops/user/Cargo.toml @@ -12,5 +12,5 @@ rivet-operation.workspace = true [dev-dependencies] chirp-worker.workspace = true - -user-get.workspace = true +chirp-workflow.workspace = true +user.workspace = true diff --git a/packages/services/faker/ops/user/tests/integration.rs b/packages/services/faker/ops/user/tests/integration.rs index 0aca4bdf8f..05c0c08fb2 100644 --- a/packages/services/faker/ops/user/tests/integration.rs +++ b/packages/services/faker/ops/user/tests/integration.rs @@ -4,8 +4,8 @@ use chirp_worker::prelude::*; async fn empty(ctx: TestCtx) { let res = op!([ctx] faker_user {}).await.unwrap(); - let get_res = op!([ctx] user_get { - user_ids: vec![res.user_id.unwrap()], + let get_res = (*ctx).op(::user::ops::get::Input { + user_ids: vec![res.user_id.unwrap().as_uuid()], }) .await .unwrap(); diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index 656d03194b..17f3a66d08 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -15,6 +15,8 @@ linode.workspace = true rivet-config.workspace = true rivet-operation.workspace = true token-create.workspace = true +upload-file-list.workspace = true +upload-get.workspace = true user-get.workspace = true user-identity-get.workspace = true diff --git a/packages/services/user/ops/profile-validate/Cargo.toml b/packages/services/user/ops/profile-validate/Cargo.toml index a18293de50..10b62fa785 100644 --- a/packages/services/user/ops/profile-validate/Cargo.toml +++ b/packages/services/user/ops/profile-validate/Cargo.toml @@ -8,9 +8,10 @@ edition.workspace = true [dependencies] rivet-operation.workspace = true chirp-client.workspace = true +chirp-workflow.workspace = true prost = "0.10" -user-get.workspace = true +user.workspace = true [dependencies.sqlx] workspace = true diff --git a/packages/services/user/ops/profile-validate/src/lib.rs b/packages/services/user/ops/profile-validate/src/lib.rs index b0d53a690d..f5a8b683d7 100644 --- a/packages/services/user/ops/profile-validate/src/lib.rs +++ b/packages/services/user/ops/profile-validate/src/lib.rs @@ -45,9 +45,12 @@ async fn handle( if ctx.display_name.is_none() || ctx.account_number.is_none() { let user_id = unwrap_ref!(ctx.user_id); - let users_res = op!([ctx] user_get { - user_ids: vec![*user_id], - }) + let users_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::get::Input { + user_ids: vec![(*user_id).as_uuid()], + }, + ) .await?; let user = users_res.users.first(); diff --git a/packages/services/user/src/ops/get.rs b/packages/services/user/src/ops/get.rs new file mode 100644 index 0000000000..221666902b --- /dev/null +++ b/packages/services/user/src/ops/get.rs @@ -0,0 +1,140 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::{common,proto}; +use proto::backend; + +#[derive(Debug)] +pub struct Input { + pub user_ids: Vec, +} + +#[derive(Debug)] +pub struct Output { + pub users: Vec +} + + +#[derive(Debug, Default, Serialize, Deserialize, sqlx::FromRow)] +struct CacheUser { + user_id: Uuid, + display_name: String, + account_number: i64, + avatar_id: String, + profile_id: Option, + join_ts: i64, + bio: String, + is_admin: bool, + delete_request_ts: Option, + delete_complete_ts: Option, +} + + +#[operation] +pub async fn get(ctx: &OperationCtx, input: &Input) -> GlobalResult { + let user_ids = input.user_ids.clone(); + + let users = ctx + .cache() + .fetch_all_json("user", user_ids, { + let ctx = ctx.clone(); + move |mut cache, user_ids| { + let ctx = ctx.clone(); + async move { + let users = sql_fetch_all!( + [ctx, CacheUser] + " + SELECT + user_id, + display_name, + account_number, + avatar_id, + profile_id, + join_ts, + bio, + is_admin, + delete_request_ts, + delete_complete_ts + FROM db_user.users + WHERE user_id = ANY($1) + ", + user_ids + ) + .await?; + + for row in users { + cache.resolve(&row.user_id.clone(), row); + } + + Ok(cache) + } + } + }) + .await?; + + let upload_ids = users + .iter() + .filter_map(|x| x.profile_id) + .map(Into::::into) + .collect::>(); + + let (upload_res, files_res) = tokio::try_join!( + op!([ctx] upload_get { + upload_ids: upload_ids.clone() + }), + op!([ctx] upload_file_list { + upload_ids: upload_ids.clone(), + }) + )?; + + Ok(Output { + users: users + .into_iter() + .map(|user| { + let profile_id = user.profile_id.map(Into::::into); + + // Fetch all information relating to the profile image + let (profile_upload_complete_ts, profile_file_name, profile_provider) = { + let upload = upload_res + .uploads + .iter() + .find(|upload| upload.upload_id == profile_id); + let file = files_res + .files + .iter() + .find(|file| file.upload_id == profile_id); + + if let (Some(upload), Some(file)) = (upload, file) { + // TODO: Why do we parse the file name here? Based on route.rs in utils shouldn't + // the entire path be present in the media url? + let profile_file_name = file + .path + .rsplit_once('/') + .map(|(_, file_name)| file_name.to_owned()) + .or(Some(file.path.clone())); + (upload.complete_ts, profile_file_name, Some(upload.provider)) + } else { + Default::default() + } + }; + + backend::user::User { + user_id: Some(user.user_id.into()), + display_name: user.display_name, + account_number: user.account_number as u32, + avatar_id: user.avatar_id, + profile_upload_id: if profile_upload_complete_ts.is_some() { + profile_id + } else { + None + }, + profile_file_name, + profile_provider, + join_ts: user.join_ts, + bio: user.bio, + is_admin: user.is_admin, + delete_request_ts: user.delete_request_ts, + delete_complete_ts: user.delete_complete_ts, + } + }) + .collect::>(), + }) +} \ No newline at end of file diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index ce39cfd97d..599d2f7020 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -1,3 +1,4 @@ +pub mod get; pub mod pending_delete_toggle; pub mod profile_validate; pub mod resolve_display_name; diff --git a/packages/services/user/src/ops/pending_delete_toggle.rs b/packages/services/user/src/ops/pending_delete_toggle.rs index 190cf1a6ad..150517721d 100644 --- a/packages/services/user/src/ops/pending_delete_toggle.rs +++ b/packages/services/user/src/ops/pending_delete_toggle.rs @@ -1,5 +1,5 @@ use chirp_workflow::prelude::*; -use proto::backend::{self, pkg::*}; +use proto::backend::{pkg::*}; use rivet_operation::prelude::proto; #[derive(Debug)] diff --git a/packages/services/user/src/ops/profile_validate.rs b/packages/services/user/src/ops/profile_validate.rs index 43524161d4..9b0c1a2e02 100644 --- a/packages/services/user/src/ops/profile_validate.rs +++ b/packages/services/user/src/ops/profile_validate.rs @@ -58,8 +58,8 @@ pub async fn profile_validate( // If either the display name or account number are missing, fetch them from the given user let (display_name, account_number) = if input.display_name.is_none() || input.account_number.is_none() { - let users_res = op!([ctx] user_get { - user_ids: vec![input.user_id.into()], + let users_res = (*ctx).op(crate::ops::get::Input { + user_ids: vec![input.user_id], }) .await?; From 2c399872fc91e9d799fb12ee35ff9a26859035c0 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Sat, 21 Dec 2024 00:43:54 +0000 Subject: [PATCH 08/11] chore(user/avatar-upload-complete): migrate ops & refs --- Cargo.lock | 4 +- packages/api/identity/Cargo.toml | 1 - packages/api/identity/src/route/identities.rs | 6 +- packages/services/user/Cargo.toml | 2 +- .../user/src/ops/avatar_upload_complete.rs | 63 +++++++++++++++++++ packages/services/user/src/ops/mod.rs | 1 + packages/services/user/worker/Cargo.toml | 1 - 7 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 packages/services/user/src/ops/avatar_upload_complete.rs diff --git a/Cargo.lock b/Cargo.lock index 22c4d877f8..12dbf42757 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -741,7 +741,6 @@ dependencies = [ "upload-prepare", "url", "user", - "user-avatar-upload-complete", "user-identity-get", "uuid", ] @@ -15914,9 +15913,9 @@ dependencies = [ "server-spec", "sqlx", "token-create", + "upload-complete", "upload-file-list", "upload-get", - "user-get", "user-identity-get", ] @@ -16101,7 +16100,6 @@ dependencies = [ "upload-list-for-user", "upload-prepare", "user", - "user-get", "user-identity-delete", ] diff --git a/packages/api/identity/Cargo.toml b/packages/api/identity/Cargo.toml index d4c437e007..d7f6d1c4c2 100644 --- a/packages/api/identity/Cargo.toml +++ b/packages/api/identity/Cargo.toml @@ -52,7 +52,6 @@ token-get.workspace = true token-revoke.workspace = true upload-prepare.workspace = true user.workspace = true -user-avatar-upload-complete.workspace = true user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/identity/src/route/identities.rs b/packages/api/identity/src/route/identities.rs index 886b9af809..68092451a9 100644 --- a/packages/api/identity/src/route/identities.rs +++ b/packages/api/identity/src/route/identities.rs @@ -290,9 +290,9 @@ pub async fn complete_avatar_upload( ) -> GlobalResult { let user_ent = ctx.auth().user(ctx.op_ctx()).await?; - op!([ctx] user_avatar_upload_complete { - user_id: Some(user_ent.user_id.into()), - upload_id: Some(upload_id.into()), + (*ctx).op(::user::ops::avatar_upload_complete::Input { + user_id: user_ent.user_id, + upload_id: upload_id, }) .await?; diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index 17f3a66d08..5a3838c9ea 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -17,7 +17,7 @@ rivet-operation.workspace = true token-create.workspace = true upload-file-list.workspace = true upload-get.workspace = true -user-get.workspace = true +upload-complete.workspace = true user-identity-get.workspace = true [dependencies.sqlx] diff --git a/packages/services/user/src/ops/avatar_upload_complete.rs b/packages/services/user/src/ops/avatar_upload_complete.rs new file mode 100644 index 0000000000..23913ff6d8 --- /dev/null +++ b/packages/services/user/src/ops/avatar_upload_complete.rs @@ -0,0 +1,63 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto; +use proto::backend::{pkg::*}; +use serde_json::json; + +#[derive(Debug)] +pub struct Input { + pub user_id: Uuid, + pub upload_id: Uuid, +} + +#[derive(Debug)] +pub struct Output {} + + +#[operation] +pub async fn avatar_upload_complete( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + let user_id = input.user_id; + + op!([ctx] upload_complete { + upload_id: Some(input.upload_id.into()), + bucket: Some("bucket-user-avatar".into()), + }) + .await?; + + // Set avatar id + sql_execute!( + [ctx] + " + UPDATE db_user.users set profile_id = $2 + WHERE user_id = $1 + ", + user_id, + input.upload_id, + ) + .await?; + + ctx.cache().purge("user", [user_id]).await?; + + msg!([ctx] user::msg::update(user_id) { + user_id: Some(user_id.into()), + }) + .await?; + + msg!([ctx] analytics::msg::event_create() { + events: vec![ + analytics::msg::event_create::Event { + event_id: Some(Uuid::new_v4().into()), + name: "user.avatar_set".into(), + properties_json: Some(serde_json::to_string(&json!({ + "user_id": user_id, + }))?), + ..Default::default() + } + ], + }) + .await?; + + Ok(Output {}) +} \ No newline at end of file diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index 599d2f7020..46200e61da 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -1,3 +1,4 @@ +pub mod avatar_upload_complete; pub mod get; pub mod pending_delete_toggle; pub mod profile_validate; diff --git a/packages/services/user/worker/Cargo.toml b/packages/services/user/worker/Cargo.toml index d548f19529..7ee723c05c 100644 --- a/packages/services/user/worker/Cargo.toml +++ b/packages/services/user/worker/Cargo.toml @@ -21,7 +21,6 @@ team-get.workspace = true team-member-list.workspace = true upload-list-for-user.workspace = true user.workspace = true -user-get.workspace = true user-identity-delete.workspace = true rivet-config.workspace = true From 72088869083e53c2bf2f3083e0c9703072318a74 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:58:47 +0000 Subject: [PATCH 09/11] chore(users): migrate user-identity ops to user --- Cargo.lock | 17 ++- packages/api/auth/Cargo.toml | 1 - packages/api/auth/src/route/identity.rs | 8 +- packages/api/cloud/Cargo.toml | 1 - packages/api/cloud/src/assert.rs | 9 +- packages/api/group/Cargo.toml | 1 - packages/api/group/src/assert.rs | 4 +- packages/api/identity/Cargo.toml | 1 - packages/api/identity/src/assert.rs | 4 +- packages/common/convert/Cargo.toml | 1 - .../common/convert/src/convert/identity.rs | 6 +- packages/common/convert/src/fetch/identity.rs | 18 ++- .../load-test/standalone/api-cloud/Cargo.toml | 3 +- .../load-test/standalone/api-cloud/src/lib.rs | 19 +-- .../standalone/watch-requests/Cargo.toml | 3 +- .../standalone/watch-requests/src/lib.rs | 19 +-- packages/services/mm/util/Cargo.toml | 3 +- packages/services/mm/util/src/verification.rs | 9 +- packages/services/mm/worker/Cargo.toml | 2 +- .../services/mm/worker/tests/lobby_find.rs | 4 +- packages/services/user/Cargo.toml | 1 + .../services/user/src/ops/identity/create.rs | 78 +++++++++++ .../services/user/src/ops/identity/delete.rs | 32 +++++ .../services/user/src/ops/identity/get.rs | 123 ++++++++++++++++++ .../services/user/src/ops/identity/mod.rs | 3 + packages/services/user/src/ops/mod.rs | 4 +- .../user/src/ops/pending_delete_toggle.rs | 4 +- packages/services/user/worker/Cargo.toml | 1 - .../user/worker/src/workers/delete.rs | 9 +- 29 files changed, 322 insertions(+), 66 deletions(-) create mode 100644 packages/services/user/src/ops/identity/create.rs create mode 100644 packages/services/user/src/ops/identity/delete.rs create mode 100644 packages/services/user/src/ops/identity/get.rs create mode 100644 packages/services/user/src/ops/identity/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 12dbf42757..c080183dba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -360,7 +360,6 @@ dependencies = [ "tracing-subscriber", "url", "user", - "user-identity-create", "user-identity-get", "uuid", ] @@ -511,7 +510,6 @@ dependencies = [ "url", "user", "user-identity-create", - "user-identity-get", "uuid", ] @@ -625,7 +623,6 @@ dependencies = [ "upload-prepare", "url", "user", - "user-identity-get", "uuid", ] @@ -741,7 +738,6 @@ dependencies = [ "upload-prepare", "url", "user", - "user-identity-get", "uuid", ] @@ -8359,6 +8355,7 @@ version = "24.6.2-rc.1" dependencies = [ "chirp-client", "chirp-worker", + "chirp-workflow", "faker-game", "faker-team", "reqwest 0.11.27", @@ -8372,7 +8369,7 @@ dependencies = [ "tracing", "tracing-logfmt", "tracing-subscriber", - "user-identity-create", + "user", ] [[package]] @@ -8467,6 +8464,7 @@ version = "24.6.2-rc.1" dependencies = [ "chirp-client", "chirp-worker", + "chirp-workflow", "faker-game", "faker-team", "reqwest 0.11.27", @@ -8480,7 +8478,7 @@ dependencies = [ "tracing", "tracing-logfmt", "tracing-subscriber", - "user-identity-create", + "user", ] [[package]] @@ -9196,7 +9194,7 @@ dependencies = [ "upload-complete", "upload-get", "upload-prepare", - "user-identity-create", + "user", ] [[package]] @@ -11755,7 +11753,6 @@ dependencies = [ "tier", "types-proto", "user", - "user-identity-get", ] [[package]] @@ -12361,6 +12358,7 @@ version = "24.6.2-rc.1" dependencies = [ "bit-vec", "chirp-client", + "chirp-workflow", "heck 0.3.3", "http 0.2.12", "ip-info", @@ -12371,7 +12369,7 @@ dependencies = [ "serde", "serde_json", "strum 0.24.1", - "user-identity-get", + "user", "uuid", ] @@ -15906,6 +15904,7 @@ version = "24.6.2-rc.1" dependencies = [ "chirp-workflow", "cluster", + "email-address-parser", "linode", "rivet-config", "rivet-operation", diff --git a/packages/api/auth/Cargo.toml b/packages/api/auth/Cargo.toml index bb48286e26..da6b9f76fb 100644 --- a/packages/api/auth/Cargo.toml +++ b/packages/api/auth/Cargo.toml @@ -39,7 +39,6 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } url = "2.2.2" user.workspace = true -user-identity-create.workspace = true uuid = { version = "1", features = ["v4"] } [dev-dependencies] diff --git a/packages/api/auth/src/route/identity.rs b/packages/api/auth/src/route/identity.rs index adb526cd60..629a99edfc 100644 --- a/packages/api/auth/src/route/identity.rs +++ b/packages/api/auth/src/route/identity.rs @@ -130,15 +130,15 @@ pub async fn complete( else { tracing::info!(user_id = %user_ent.user_id, "creating new identity for guest"); - op!([ctx] user_identity_create { - user_id: Some(Into::into(user_ent.user_id)), - identity: Some(backend::user_identity::Identity { + (*ctx).op(::user::ops::identity::create::Input { + user_id: user_ent.user_id, + identity: backend::user_identity::Identity { kind: Some(backend::user_identity::identity::Kind::Email( backend::user_identity::identity::Email { email: res.email.clone(), } )) - }) + } }) .await?; diff --git a/packages/api/cloud/Cargo.toml b/packages/api/cloud/Cargo.toml index d102043a32..4f9bbb82df 100644 --- a/packages/api/cloud/Cargo.toml +++ b/packages/api/cloud/Cargo.toml @@ -109,7 +109,6 @@ upload-file-list.workspace = true upload-get.workspace = true upload-prepare.workspace = true user.workspace = true -user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/cloud/src/assert.rs b/packages/api/cloud/src/assert.rs index 009b938784..aa5bfeaffd 100644 --- a/packages/api/cloud/src/assert.rs +++ b/packages/api/cloud/src/assert.rs @@ -7,9 +7,12 @@ use crate::auth::Auth; /// Validates that a given user ID is registered. pub async fn user_registered(ctx: &OperationContext<()>, user_id: Uuid) -> GlobalResult<()> { // If the user has at least one identity they are considered registered - let identity = op!([ctx] user_identity_get { - user_ids: vec![user_id.into()] - }) + let identity = chirp_workflow::compat::op( + &ctx, + ::user::ops::identity::get::Input { + user_ids: vec![user_id] + }, + ) .await?; let identities = &unwrap_ref!(identity.users.first()).identities; diff --git a/packages/api/group/Cargo.toml b/packages/api/group/Cargo.toml index c4f385a6b2..911e6ff7e3 100644 --- a/packages/api/group/Cargo.toml +++ b/packages/api/group/Cargo.toml @@ -52,7 +52,6 @@ team-user-ban-list.workspace = true token-revoke.workspace = true upload-prepare.workspace = true user.workspace = true -user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/group/src/assert.rs b/packages/api/group/src/assert.rs index 96fa848992..0635d2afa9 100644 --- a/packages/api/group/src/assert.rs +++ b/packages/api/group/src/assert.rs @@ -6,8 +6,8 @@ use crate::auth::Auth; /// Validates that a given user ID is registered. pub async fn user_registered(ctx: &Ctx, user_id: Uuid) -> GlobalResult<()> { // If the user has at least one identity they are considered registered - let identity = op!([ctx] user_identity_get { - user_ids: vec![user_id.into()] + let identity = (*ctx).op(::user::ops::identity::get::Input { + user_ids: vec![user_id] }) .await?; diff --git a/packages/api/identity/Cargo.toml b/packages/api/identity/Cargo.toml index d7f6d1c4c2..216a97bf22 100644 --- a/packages/api/identity/Cargo.toml +++ b/packages/api/identity/Cargo.toml @@ -52,7 +52,6 @@ token-get.workspace = true token-revoke.workspace = true upload-prepare.workspace = true user.workspace = true -user-identity-get.workspace = true rivet-config.workspace = true rivet-env.workspace = true diff --git a/packages/api/identity/src/assert.rs b/packages/api/identity/src/assert.rs index 96fa848992..0635d2afa9 100644 --- a/packages/api/identity/src/assert.rs +++ b/packages/api/identity/src/assert.rs @@ -6,8 +6,8 @@ use crate::auth::Auth; /// Validates that a given user ID is registered. pub async fn user_registered(ctx: &Ctx, user_id: Uuid) -> GlobalResult<()> { // If the user has at least one identity they are considered registered - let identity = op!([ctx] user_identity_get { - user_ids: vec![user_id.into()] + let identity = (*ctx).op(::user::ops::identity::get::Input { + user_ids: vec![user_id] }) .await?; diff --git a/packages/common/convert/Cargo.toml b/packages/common/convert/Cargo.toml index dd47afa125..00bcbc66fe 100644 --- a/packages/common/convert/Cargo.toml +++ b/packages/common/convert/Cargo.toml @@ -37,7 +37,6 @@ team-profile-validate.workspace = true team-validate.workspace = true tier.workspace = true user.workspace = true -user-identity-get.workspace = true rivet-api.workspace = true rivet-group-server.workspace = true diff --git a/packages/common/convert/src/convert/identity.rs b/packages/common/convert/src/convert/identity.rs index e5c96f0268..48c3731a6a 100644 --- a/packages/common/convert/src/convert/identity.rs +++ b/packages/common/convert/src/convert/identity.rs @@ -1,6 +1,6 @@ use rivet_api::models; use rivet_operation::prelude::*; -use types_proto::rivet::backend::{self, pkg::*}; +use types_proto::rivet::backend::{self}; use crate::{convert, fetch, ApiTryInto}; @@ -51,7 +51,7 @@ pub fn summary( #[derive(Debug)] pub struct ProfileCtx<'a> { pub teams_ctx: &'a fetch::identity::TeamsCtx, - pub linked_accounts: &'a [user_identity::get::response::User], + pub linked_accounts: &'a [::user::ops::identity::get::User], pub self_is_game_linked: bool, } @@ -69,7 +69,7 @@ pub fn profile( let identities = unwrap!(pctx .linked_accounts .iter() - .find(|identity| identity.user_id == user.user_id)); + .find(|identity| identity.user_id == user_id)); let identities = &identities.identities; // If the user has at least one identity they are considered registered let is_registered = !identities.is_empty(); diff --git a/packages/common/convert/src/fetch/identity.rs b/packages/common/convert/src/fetch/identity.rs index e425de01c0..9d4f69f4f3 100644 --- a/packages/common/convert/src/fetch/identity.rs +++ b/packages/common/convert/src/fetch/identity.rs @@ -1,5 +1,5 @@ use proto::{ - backend::{self, pkg::*}, + backend::{self}, common, }; use rivet_api::models; @@ -147,9 +147,15 @@ async fn teams(ctx: &OperationContext<()>, user_ids: Vec) -> Globa async fn linked_accounts( ctx: &OperationContext<()>, user_ids: Vec, -) -> GlobalResult { - op!([ctx] user_identity_get { - user_ids: user_ids.clone(), - }) - .await +) -> GlobalResult<::user::ops::identity::get::Output> { + Ok(chirp_workflow::compat::op( + &ctx, + ::user::ops::identity::get::Input { + user_ids: user_ids + .iter() + .map(|i| i.as_uuid()) + .collect::>() + }, + ) + .await?) } diff --git a/packages/services/load-test/standalone/api-cloud/Cargo.toml b/packages/services/load-test/standalone/api-cloud/Cargo.toml index 26c6bac6e0..81ef886927 100644 --- a/packages/services/load-test/standalone/api-cloud/Cargo.toml +++ b/packages/services/load-test/standalone/api-cloud/Cargo.toml @@ -7,6 +7,7 @@ edition.workspace = true [dependencies] chirp-client.workspace = true +chirp-workflow.workspace = true rivet-operation.workspace = true rivet-connection.workspace = true rivet-runtime.workspace = true @@ -23,7 +24,7 @@ reqwest = "0.11" faker-game.workspace = true faker-team.workspace = true -user-identity-create.workspace = true +user.workspace = true token-create.workspace = true rivet-config.workspace = true diff --git a/packages/services/load-test/standalone/api-cloud/src/lib.rs b/packages/services/load-test/standalone/api-cloud/src/lib.rs index 15a685bee7..65ce64f882 100644 --- a/packages/services/load-test/standalone/api-cloud/src/lib.rs +++ b/packages/services/load-test/standalone/api-cloud/src/lib.rs @@ -44,14 +44,17 @@ pub async fn run_from_env( let primary_user_id = create_res.member_user_ids[0].as_uuid(); // Register user - op!([ctx] user_identity_create { - user_id: Some(primary_user_id.into()), - identity: Some(backend::user_identity::Identity { - kind: Some(backend::user_identity::identity::Kind::Email(backend::user_identity::identity::Email { - email: util::faker::email() - })) - }) - }) + chirp_workflow::compat::op( + &ctx, + ::user::ops::identity::create::Input { + user_id: primary_user_id, + identity: backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email(backend::user_identity::identity::Email { + email: util::faker::email() + })) + } + } + ) .await?; (team_id, primary_user_id) diff --git a/packages/services/load-test/standalone/watch-requests/Cargo.toml b/packages/services/load-test/standalone/watch-requests/Cargo.toml index 123a94828f..5fb12c92a5 100644 --- a/packages/services/load-test/standalone/watch-requests/Cargo.toml +++ b/packages/services/load-test/standalone/watch-requests/Cargo.toml @@ -7,6 +7,7 @@ edition.workspace = true [dependencies] chirp-client.workspace = true +chirp-workflow.workspace = true rivet-operation.workspace = true rivet-connection.workspace = true rivet-runtime.workspace = true @@ -19,7 +20,7 @@ reqwest = "0.11" faker-game.workspace = true faker-team.workspace = true -user-identity-create.workspace = true +user.workspace = true token-create.workspace = true rivet-config.workspace = true diff --git a/packages/services/load-test/standalone/watch-requests/src/lib.rs b/packages/services/load-test/standalone/watch-requests/src/lib.rs index c538e46ae7..ad7dca82b8 100644 --- a/packages/services/load-test/standalone/watch-requests/src/lib.rs +++ b/packages/services/load-test/standalone/watch-requests/src/lib.rs @@ -44,14 +44,17 @@ pub async fn run_from_env( let primary_user_id = create_res.member_user_ids[0].as_uuid(); // Register user - op!([ctx] user_identity_create { - user_id: Some(primary_user_id.into()), - identity: Some(backend::user_identity::Identity { - kind: Some(backend::user_identity::identity::Kind::Email(backend::user_identity::identity::Email { - email: util::faker::email() - })) - }) - }) + chirp_workflow::compat::op( + &ctx, + ::user::ops::identity::create::Input { + user_id: primary_user_id, + identity: backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email(backend::user_identity::identity::Email { + email: util::faker::email() + })) + } + } + ) .await?; (team_id, primary_user_id) diff --git a/packages/services/mm/util/Cargo.toml b/packages/services/mm/util/Cargo.toml index 5a9b788353..83b76264a8 100644 --- a/packages/services/mm/util/Cargo.toml +++ b/packages/services/mm/util/Cargo.toml @@ -8,6 +8,7 @@ edition.workspace = true [dependencies] bit-vec = "0.6" chirp-client.workspace = true +chirp-workflow.workspace = true heck = "0.3" http = "0.2" rivet-operation.workspace = true @@ -20,4 +21,4 @@ uuid = { version = "1", features = ["v4", "serde"] } ip-info.workspace = true mm-lobby-list-for-user-id.workspace = true region-get.workspace = true -user-identity-get.workspace = true +user.workspace = true diff --git a/packages/services/mm/util/src/verification.rs b/packages/services/mm/util/src/verification.rs index ae51d87f55..2df5828944 100644 --- a/packages/services/mm/util/src/verification.rs +++ b/packages/services/mm/util/src/verification.rs @@ -231,9 +231,12 @@ pub async fn verify_config( // Verify identity requirement match (highest_identity_requirement, opts.user_id) { (backend::matchmaker::IdentityRequirement::Registered, Some(user_id)) => { - let user_identities_res = op!([ctx] user_identity_get { - user_ids: vec![user_id.into()], - }) + let user_identities_res = chirp_workflow::compat::op( + &ctx, + ::user::ops::identity::get::Input { + user_ids: vec![user_id] + }, + ) .await?; let user = unwrap!( user_identities_res.users.first(), diff --git a/packages/services/mm/worker/Cargo.toml b/packages/services/mm/worker/Cargo.toml index 0bdba0c5b1..613d6827ee 100644 --- a/packages/services/mm/worker/Cargo.toml +++ b/packages/services/mm/worker/Cargo.toml @@ -74,4 +74,4 @@ mm-config-version-get.workspace = true mm-lobby-get.workspace = true mm-lobby-player-count.workspace = true mm-player-count-for-namespace.workspace = true -user-identity-create.workspace = true +user.workspace = true diff --git a/packages/services/mm/worker/tests/lobby_find.rs b/packages/services/mm/worker/tests/lobby_find.rs index f014bad178..8f0592aefa 100644 --- a/packages/services/mm/worker/tests/lobby_find.rs +++ b/packages/services/mm/worker/tests/lobby_find.rs @@ -527,8 +527,8 @@ async fn registered_verification(ctx: TestCtx) { ); let email = util::faker::email(); - op!([ctx] user_identity_create { - user_id: user_res.user_id, + ctx.op(::user::ops::identity::create::Input { + user_id: user_id, identity: Some(backend::user_identity::Identity { kind: Some(backend::user_identity::identity::Kind::Email( backend::user_identity::identity::Email { diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index 5a3838c9ea..8406ec5a71 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -10,6 +10,7 @@ serde = { version = "1.0.198", features = ["derive"] } chirp-workflow.workspace = true cluster.workspace = true +email-address-parser = "1.0.1" server-spec.workspace = true linode.workspace = true rivet-config.workspace = true diff --git a/packages/services/user/src/ops/identity/create.rs b/packages/services/user/src/ops/identity/create.rs new file mode 100644 index 0000000000..92123e17b4 --- /dev/null +++ b/packages/services/user/src/ops/identity/create.rs @@ -0,0 +1,78 @@ +use chirp_workflow::prelude::*; +use email_address_parser::EmailAddress; +use rivet_operation::prelude::proto; +use proto::backend::{self,pkg::*}; +use serde_json::json; + +#[derive(Debug)] +pub struct Input { + pub user_id: Uuid, + pub identity: backend::user_identity::Identity, +} + +#[derive(Debug)] +pub struct Output {} + + +#[operation] +pub async fn create( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + let user_id = input.user_id; + let identity = &input.identity; + let identity_kind = unwrap_ref!(identity.kind); + + match &identity_kind { + backend::user_identity::identity::Kind::Email(email) => { + ensure!(EmailAddress::is_valid(&email.email, None), "invalid email"); + + sql_execute!( + [ctx] + " + INSERT INTO db_user_identity.emails (email, user_id, create_ts) + VALUES ($1, $2, $3) + ", + &email.email, + user_id, + ctx.ts(), + ) + .await?; + + msg!([ctx] analytics::msg::event_create() { + events: vec![ + analytics::msg::event_create::Event { + event_id: Some(Uuid::new_v4().into()), + name: "user_identity.create".into(), + properties_json: Some(serde_json::to_string(&json!({ + "identity_email": email.email, + "user_id": user_id, + }))?), + ..Default::default() + } + ], + }) + .await?; + } + backend::user_identity::identity::Kind::DefaultUser(_) => { + bail!("cannot create default user identity") + } + } + + ctx.cache() + .purge("user_identity.identity", [user_id]) + .await?; + + msg!([ctx] user_identity::msg::create_complete(user_id) { + user_id: Some(user_id.into()), + identity: Some(identity.clone()), + }) + .await?; + + msg!([ctx] user::msg::update(user_id) { + user_id: Some(user_id.into()), + }) + .await?; + + Ok(Output {}) +} \ No newline at end of file diff --git a/packages/services/user/src/ops/identity/delete.rs b/packages/services/user/src/ops/identity/delete.rs new file mode 100644 index 0000000000..13254049d1 --- /dev/null +++ b/packages/services/user/src/ops/identity/delete.rs @@ -0,0 +1,32 @@ +use chirp_workflow::prelude::*; + +#[derive(Debug)] +pub struct Input { + pub user_ids: Vec +} + +#[derive(Debug)] +pub struct Output {} + + +#[operation] +pub async fn create( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + sql_execute!( + [ctx] + " + DELETE FROM db_user_identity.emails + WHERE user_id = ANY($1) + ", + &input.user_ids, + ) + .await?; + + ctx.cache() + .purge("user_identity.identity", input.user_ids.clone()) + .await?; + + Ok(Output {}) +} \ No newline at end of file diff --git a/packages/services/user/src/ops/identity/get.rs b/packages/services/user/src/ops/identity/get.rs new file mode 100644 index 0000000000..ce352f9503 --- /dev/null +++ b/packages/services/user/src/ops/identity/get.rs @@ -0,0 +1,123 @@ +use chirp_workflow::prelude::*; +use proto::backend::{self}; +use rivet_operation::prelude::{proto}; + + +#[derive(Debug, Default, Serialize, Deserialize, sqlx::FromRow)] +struct CacheUserIdentity { + user_id: Uuid, + email: Option, +} + +#[derive(Debug)] +pub struct Input { + pub user_ids: Vec, +} + +#[derive(Debug)] +pub struct Output { + pub users: Vec +} + +#[derive(Debug)] +pub struct User { + pub user_id: Uuid, + pub identities: Vec +} + + +#[operation] +pub async fn get( + ctx: &OperationCtx, + input: &Input +) -> GlobalResult { + let is_development = ctx.config().server()?.rivet.auth.access_kind + == rivet_config::config::rivet::AccessKind::Development; + + let user_ids = &input.user_ids; + // Get the user display names + let users = ctx.op(crate::ops::get::Input { + user_ids: user_ids.clone(), + }) + .await?; + + // Fetch the identities + let identities = ctx + .cache() + .fetch_all_json("user_identity.identity", user_ids.clone(), { + let ctx = ctx.clone(); + move |mut cache, user_ids| { + let ctx = ctx.clone(); + async move { + let identity_rows = sql_fetch_all!( + [ctx, CacheUserIdentity] + " + SELECT e.user_id AS user_id, e.email + FROM db_user_identity.emails as e + WHERE e.user_id = ANY($1) + ", + &user_ids, + ) + .await?; + + for row in identity_rows { + cache.resolve( + &row.user_id.clone(), + row, + ); + } + + Ok(cache) + } + } + }) + .await?; + + let users = user_ids + .iter() + .filter_map(|user_id| { + // Find matching user + let Some(user) = users + .users + .iter() + .find(|x| x.user_id.map(|x| x.as_uuid()) == Some(*user_id)) + else { + return None; + }; + + // Find matching identities + let mut identities = identities + .iter() + .filter(|x| x.user_id == *user_id) + .flat_map(|x| { + IntoIterator::into_iter([x.email.as_ref().map(|email| { + backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email( + backend::user_identity::identity::Email { + email: email.clone(), + }, + )), + } + })]) + .flatten() + }) + .collect::>(); + + // Inject identity for development users since they should behave like registered users. + if is_development && user.display_name == util::dev_defaults::USER_NAME { + identities.push(backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::DefaultUser( + backend::user_identity::identity::DefaultUser {}, + )), + }) + } + + Some(User { + user_id: *user_id, + identities, + }) + }) + .collect::>(); + + Ok(Output { users }) +} diff --git a/packages/services/user/src/ops/identity/mod.rs b/packages/services/user/src/ops/identity/mod.rs new file mode 100644 index 0000000000..ca15fa0ec9 --- /dev/null +++ b/packages/services/user/src/ops/identity/mod.rs @@ -0,0 +1,3 @@ +pub mod create; +pub mod delete; +pub mod get; \ No newline at end of file diff --git a/packages/services/user/src/ops/mod.rs b/packages/services/user/src/ops/mod.rs index 46200e61da..3dfc7ed2ae 100644 --- a/packages/services/user/src/ops/mod.rs +++ b/packages/services/user/src/ops/mod.rs @@ -5,4 +5,6 @@ pub mod profile_validate; pub mod resolve_display_name; pub mod resolve_email; pub mod team_list; -pub mod token_create; \ No newline at end of file +pub mod token_create; + +pub mod identity; \ No newline at end of file diff --git a/packages/services/user/src/ops/pending_delete_toggle.rs b/packages/services/user/src/ops/pending_delete_toggle.rs index 150517721d..ff762296b4 100644 --- a/packages/services/user/src/ops/pending_delete_toggle.rs +++ b/packages/services/user/src/ops/pending_delete_toggle.rs @@ -21,8 +21,8 @@ pub async fn pending_delete_toggle( let user_id = input.user_id; // Verify the user is registered - let identity = op!([ctx] user_identity_get { - user_ids: vec![user_id.into()], + let identity = ctx.op(crate::ops::identity::get::Input { + user_ids: vec![user_id] }) .await?; let identities = &unwrap_ref!(identity.users.first()).identities; diff --git a/packages/services/user/worker/Cargo.toml b/packages/services/user/worker/Cargo.toml index 7ee723c05c..d46c5d5b7c 100644 --- a/packages/services/user/worker/Cargo.toml +++ b/packages/services/user/worker/Cargo.toml @@ -21,7 +21,6 @@ team-get.workspace = true team-member-list.workspace = true upload-list-for-user.workspace = true user.workspace = true -user-identity-delete.workspace = true rivet-config.workspace = true [dev-dependencies] diff --git a/packages/services/user/worker/src/workers/delete.rs b/packages/services/user/worker/src/workers/delete.rs index a45bd8f524..eec89d14ef 100644 --- a/packages/services/user/worker/src/workers/delete.rs +++ b/packages/services/user/worker/src/workers/delete.rs @@ -13,9 +13,12 @@ async fn worker(ctx: &OperationContext) -> GlobalRes // Delete user identities { - op!([ctx] user_identity_delete { - user_ids: vec![user_id.into()], - }) + chirp_workflow::compat::op( + &ctx, + ::user::ops::identity::delete::Input { + user_ids: vec![user_id] + } + ) .await?; } From c43352dac6cc4b0946b5b9b32af7a61ec493ea48 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Mon, 30 Dec 2024 23:07:04 +0000 Subject: [PATCH 10/11] chore(user-identity/db): migrate migrations to user --- .../db/user/migrations/20200101000001_init.down.sql} | 0 .../db/user/migrations/20200101000001_init.up.sql} | 0 .../db/user}/migrations/20230101105612_index_user.down.sql | 0 .../db/user}/migrations/20230101105612_index_user.up.sql | 0 .../db/user}/migrations/20231116005712_access_tokens.down.sql | 0 .../db/user}/migrations/20231116005712_access_tokens.up.sql | 0 .../user}/migrations/20241104000750_drop_access_tokens.down.sql | 0 .../db/user}/migrations/20241104000750_drop_access_tokens.up.sql | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename packages/services/{user-identity/db/user-identity/migrations/20200101000000_init.down.sql => user/db/user/migrations/20200101000001_init.down.sql} (100%) rename packages/services/{user-identity/db/user-identity/migrations/20200101000000_init.up.sql => user/db/user/migrations/20200101000001_init.up.sql} (100%) rename packages/services/{user-identity/db/user-identity => user/db/user}/migrations/20230101105612_index_user.down.sql (100%) rename packages/services/{user-identity/db/user-identity => user/db/user}/migrations/20230101105612_index_user.up.sql (100%) rename packages/services/{user-identity/db/user-identity => user/db/user}/migrations/20231116005712_access_tokens.down.sql (100%) rename packages/services/{user-identity/db/user-identity => user/db/user}/migrations/20231116005712_access_tokens.up.sql (100%) rename packages/services/{user-identity/db/user-identity => user/db/user}/migrations/20241104000750_drop_access_tokens.down.sql (100%) rename packages/services/{user-identity/db/user-identity => user/db/user}/migrations/20241104000750_drop_access_tokens.up.sql (100%) diff --git a/packages/services/user-identity/db/user-identity/migrations/20200101000000_init.down.sql b/packages/services/user/db/user/migrations/20200101000001_init.down.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20200101000000_init.down.sql rename to packages/services/user/db/user/migrations/20200101000001_init.down.sql diff --git a/packages/services/user-identity/db/user-identity/migrations/20200101000000_init.up.sql b/packages/services/user/db/user/migrations/20200101000001_init.up.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20200101000000_init.up.sql rename to packages/services/user/db/user/migrations/20200101000001_init.up.sql diff --git a/packages/services/user-identity/db/user-identity/migrations/20230101105612_index_user.down.sql b/packages/services/user/db/user/migrations/20230101105612_index_user.down.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20230101105612_index_user.down.sql rename to packages/services/user/db/user/migrations/20230101105612_index_user.down.sql diff --git a/packages/services/user-identity/db/user-identity/migrations/20230101105612_index_user.up.sql b/packages/services/user/db/user/migrations/20230101105612_index_user.up.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20230101105612_index_user.up.sql rename to packages/services/user/db/user/migrations/20230101105612_index_user.up.sql diff --git a/packages/services/user-identity/db/user-identity/migrations/20231116005712_access_tokens.down.sql b/packages/services/user/db/user/migrations/20231116005712_access_tokens.down.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20231116005712_access_tokens.down.sql rename to packages/services/user/db/user/migrations/20231116005712_access_tokens.down.sql diff --git a/packages/services/user-identity/db/user-identity/migrations/20231116005712_access_tokens.up.sql b/packages/services/user/db/user/migrations/20231116005712_access_tokens.up.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20231116005712_access_tokens.up.sql rename to packages/services/user/db/user/migrations/20231116005712_access_tokens.up.sql diff --git a/packages/services/user-identity/db/user-identity/migrations/20241104000750_drop_access_tokens.down.sql b/packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.down.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20241104000750_drop_access_tokens.down.sql rename to packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.down.sql diff --git a/packages/services/user-identity/db/user-identity/migrations/20241104000750_drop_access_tokens.up.sql b/packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.up.sql similarity index 100% rename from packages/services/user-identity/db/user-identity/migrations/20241104000750_drop_access_tokens.up.sql rename to packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.up.sql From be1bf747c2c5c48841ef05b7e55ebca141127338 Mon Sep 17 00:00:00 2001 From: ABCxFF <79597906+ABCxFF@users.noreply.github.com> Date: Thu, 2 Jan 2025 19:00:41 +0000 Subject: [PATCH 11/11] chore(users): migrate tests --- Cargo.lock | 546 +++++++++--------- packages/api/cloud/src/auth.rs | 2 +- packages/api/group/tests/basic.rs | 2 +- packages/api/portal/tests/basic.rs | 2 +- packages/infra/server/src/run_config.rs | 2 +- packages/services/user/Cargo.toml | 10 +- .../migrations/20200101000000_init.down.sql} | 0 .../migrations/20200101000000_init.up.sql} | 0 .../20230101105612_index_user.down.sql | 0 .../20230101105612_index_user.up.sql | 0 .../20231116005712_access_tokens.down.sql | 0 .../20231116005712_access_tokens.up.sql | 0 ...20241104000750_drop_access_tokens.down.sql | 0 .../20241104000750_drop_access_tokens.up.sql | 0 .../user/tests/avatar_upload_complete.rs | 62 ++ packages/services/user/tests/get.rs | 72 +++ .../services/user/tests/identity_create.rs | 35 ++ .../services/user/tests/identity_delete.rs | 41 ++ packages/services/user/tests/identity_get.rs | 42 ++ .../user/tests/pending_delete_toggle.rs | 67 +++ .../services/user/tests/profile_validate.rs | 18 + packages/services/user/tests/resolve_email.rs | 35 ++ packages/services/user/tests/team_list.rs | 49 ++ packages/services/user/tests/token_create.rs | 18 + 24 files changed, 725 insertions(+), 278 deletions(-) rename packages/services/user/db/{user/migrations/20200101000001_init.down.sql => user-identity/migrations/20200101000000_init.down.sql} (100%) rename packages/services/user/db/{user/migrations/20200101000001_init.up.sql => user-identity/migrations/20200101000000_init.up.sql} (100%) rename packages/services/user/db/{user => user-identity}/migrations/20230101105612_index_user.down.sql (100%) rename packages/services/user/db/{user => user-identity}/migrations/20230101105612_index_user.up.sql (100%) rename packages/services/user/db/{user => user-identity}/migrations/20231116005712_access_tokens.down.sql (100%) rename packages/services/user/db/{user => user-identity}/migrations/20231116005712_access_tokens.up.sql (100%) rename packages/services/user/db/{user => user-identity}/migrations/20241104000750_drop_access_tokens.down.sql (100%) rename packages/services/user/db/{user => user-identity}/migrations/20241104000750_drop_access_tokens.up.sql (100%) create mode 100644 packages/services/user/tests/avatar_upload_complete.rs create mode 100644 packages/services/user/tests/get.rs create mode 100644 packages/services/user/tests/identity_create.rs create mode 100644 packages/services/user/tests/identity_delete.rs create mode 100644 packages/services/user/tests/identity_get.rs create mode 100644 packages/services/user/tests/pending_delete_toggle.rs create mode 100644 packages/services/user/tests/profile_validate.rs create mode 100644 packages/services/user/tests/resolve_email.rs create mode 100644 packages/services/user/tests/team_list.rs create mode 100644 packages/services/user/tests/token_create.rs diff --git a/Cargo.lock b/Cargo.lock index c080183dba..cbe5dc607c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -255,7 +255,7 @@ dependencies = [ [[package]] name = "api-actor" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "base64 0.13.1", @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "api-auth" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "api-cf-verification" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -401,7 +401,7 @@ dependencies = [ [[package]] name = "api-cloud" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -515,7 +515,7 @@ dependencies = [ [[package]] name = "api-games" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "base64 0.13.1", @@ -575,7 +575,7 @@ dependencies = [ [[package]] name = "api-group" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -628,7 +628,7 @@ dependencies = [ [[package]] name = "api-helper" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper-macros", "async-trait", @@ -672,7 +672,7 @@ dependencies = [ [[package]] name = "api-helper-macros" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "proc-macro-error", "proc-macro2", @@ -682,7 +682,7 @@ dependencies = [ [[package]] name = "api-identity" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -743,7 +743,7 @@ dependencies = [ [[package]] name = "api-job" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -781,7 +781,7 @@ dependencies = [ [[package]] name = "api-matchmaker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -849,7 +849,7 @@ dependencies = [ [[package]] name = "api-monolith-edge" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "api-provision", @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "api-monolith-public" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-actor", "api-auth", @@ -899,7 +899,7 @@ dependencies = [ [[package]] name = "api-portal" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -943,7 +943,7 @@ dependencies = [ [[package]] name = "api-provision" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -975,7 +975,7 @@ dependencies = [ [[package]] name = "api-status" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -1022,7 +1022,7 @@ dependencies = [ [[package]] name = "api-traefik-provider" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -1072,7 +1072,7 @@ dependencies = [ [[package]] name = "api-ui" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "api-helper", "async-trait", @@ -2125,7 +2125,7 @@ dependencies = [ [[package]] name = "build" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "acme-lib", "anyhow", @@ -2167,7 +2167,7 @@ dependencies = [ [[package]] name = "build-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2188,7 +2188,7 @@ dependencies = [ [[package]] name = "build-default-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2213,7 +2213,7 @@ dependencies = [ [[package]] name = "build-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2226,7 +2226,7 @@ dependencies = [ [[package]] name = "build-list-for-env" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2239,7 +2239,7 @@ dependencies = [ [[package]] name = "build-list-for-game" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2334,7 +2334,7 @@ dependencies = [ [[package]] name = "captcha-hcaptcha-config-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2345,7 +2345,7 @@ dependencies = [ [[package]] name = "captcha-hcaptcha-verify" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2357,7 +2357,7 @@ dependencies = [ [[package]] name = "captcha-request" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2370,7 +2370,7 @@ dependencies = [ [[package]] name = "captcha-turnstile-config-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2381,7 +2381,7 @@ dependencies = [ [[package]] name = "captcha-turnstile-verify" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2393,7 +2393,7 @@ dependencies = [ [[package]] name = "captcha-verify" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "captcha-hcaptcha-config-get", "captcha-hcaptcha-verify", @@ -2454,7 +2454,7 @@ dependencies = [ [[package]] name = "cdn-namespace-auth-user-remove" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-auth-user-update", "cdn-namespace-create", @@ -2467,7 +2467,7 @@ dependencies = [ [[package]] name = "cdn-namespace-auth-user-update" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-create", "chirp-client", @@ -2479,7 +2479,7 @@ dependencies = [ [[package]] name = "cdn-namespace-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2490,7 +2490,7 @@ dependencies = [ [[package]] name = "cdn-namespace-domain-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2504,7 +2504,7 @@ dependencies = [ [[package]] name = "cdn-namespace-domain-remove" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-domain-create", "chirp-client", @@ -2519,7 +2519,7 @@ dependencies = [ [[package]] name = "cdn-namespace-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-create", "cdn-namespace-domain-create", @@ -2533,7 +2533,7 @@ dependencies = [ [[package]] name = "cdn-namespace-resolve-domain" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-domain-create", "chirp-client", @@ -2546,7 +2546,7 @@ dependencies = [ [[package]] name = "cdn-ns-auth-type-set" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-create", "chirp-client", @@ -2558,7 +2558,7 @@ dependencies = [ [[package]] name = "cdn-ns-enable-domain-public-auth-set" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-create", "chirp-client", @@ -2570,7 +2570,7 @@ dependencies = [ [[package]] name = "cdn-site-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2587,7 +2587,7 @@ dependencies = [ [[package]] name = "cdn-site-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2600,7 +2600,7 @@ dependencies = [ [[package]] name = "cdn-site-list-for-game" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2613,7 +2613,7 @@ dependencies = [ [[package]] name = "cdn-version-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2626,7 +2626,7 @@ dependencies = [ [[package]] name = "cdn-version-prepare" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-site-get", "chirp-client", @@ -2640,7 +2640,7 @@ dependencies = [ [[package]] name = "cdn-version-publish" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-version-get", "chirp-client", @@ -2656,7 +2656,7 @@ dependencies = [ [[package]] name = "cdn-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-get", "cdn-site-get", @@ -2690,7 +2690,7 @@ dependencies = [ [[package]] name = "cf-custom-hostname-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2701,7 +2701,7 @@ dependencies = [ [[package]] name = "cf-custom-hostname-list-for-namespace-id" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2712,7 +2712,7 @@ dependencies = [ [[package]] name = "cf-custom-hostname-resolve-hostname" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -2723,7 +2723,7 @@ dependencies = [ [[package]] name = "cf-custom-hostname-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cf-custom-hostname-get", "cf-custom-hostname-list-for-namespace-id", @@ -2763,7 +2763,7 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chirp-client" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-perf", "chirp-types", @@ -2791,7 +2791,7 @@ dependencies = [ [[package]] name = "chirp-metrics" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "lazy_static", "rivet-metrics", @@ -2799,7 +2799,7 @@ dependencies = [ [[package]] name = "chirp-perf" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "lazy_static", "prost 0.10.4", @@ -2816,14 +2816,14 @@ dependencies = [ [[package]] name = "chirp-types" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "prost 0.10.4", ] [[package]] name = "chirp-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "async-trait", "chirp-client", @@ -2861,7 +2861,7 @@ dependencies = [ [[package]] name = "chirp-worker-attributes" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-worker", "proc-macro2", @@ -2872,7 +2872,7 @@ dependencies = [ [[package]] name = "chirp-workflow" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -2910,7 +2910,7 @@ dependencies = [ [[package]] name = "chirp-workflow-macros" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "proc-macro2", "quote", @@ -3066,7 +3066,7 @@ dependencies = [ [[package]] name = "cloud-default-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3097,7 +3097,7 @@ dependencies = [ [[package]] name = "cloud-device-link-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3109,7 +3109,7 @@ dependencies = [ [[package]] name = "cloud-game-config-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3120,7 +3120,7 @@ dependencies = [ [[package]] name = "cloud-game-config-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3132,7 +3132,7 @@ dependencies = [ [[package]] name = "cloud-game-token-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3145,7 +3145,7 @@ dependencies = [ [[package]] name = "cloud-namespace-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-create", "chirp-client", @@ -3163,7 +3163,7 @@ dependencies = [ [[package]] name = "cloud-namespace-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-get", "chirp-client", @@ -3180,7 +3180,7 @@ dependencies = [ [[package]] name = "cloud-namespace-token-development-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3195,7 +3195,7 @@ dependencies = [ [[package]] name = "cloud-namespace-token-public-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3210,7 +3210,7 @@ dependencies = [ [[package]] name = "cloud-version-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-version-get", "chirp-client", @@ -3228,7 +3228,7 @@ dependencies = [ [[package]] name = "cloud-version-publish" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-version-prepare", "cdn-version-publish", @@ -3250,7 +3250,7 @@ dependencies = [ [[package]] name = "cloud-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3282,7 +3282,7 @@ dependencies = [ [[package]] name = "cluster" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "acme-lib", "anyhow", @@ -3321,7 +3321,7 @@ dependencies = [ [[package]] name = "cluster-datacenter-tls-renew" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", @@ -3340,7 +3340,7 @@ dependencies = [ [[package]] name = "cluster-default-update" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3361,7 +3361,7 @@ dependencies = [ [[package]] name = "cluster-gc" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", @@ -3380,7 +3380,7 @@ dependencies = [ [[package]] name = "cluster-metrics-publish" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", @@ -3864,7 +3864,7 @@ dependencies = [ [[package]] name = "custom-user-avatar-list-for-game" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -3879,7 +3879,7 @@ dependencies = [ [[package]] name = "custom-user-avatar-upload-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -4000,7 +4000,7 @@ checksum = "41b319d1b62ffbd002e057f36bebd1f42b9f97927c9577461d855f3513c4289f" [[package]] name = "debug-email-res" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -4030,7 +4030,7 @@ checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" [[package]] name = "deno-embed" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "dirs", @@ -5236,7 +5236,7 @@ dependencies = [ [[package]] name = "ds" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "bit-vec", "build", @@ -5297,7 +5297,7 @@ dependencies = [ [[package]] name = "ds-log-export" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5311,7 +5311,7 @@ dependencies = [ [[package]] name = "ds-log-read" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5346,7 +5346,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "dynamic-config" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-workflow", "indoc 2.0.5", @@ -5522,7 +5522,7 @@ dependencies = [ [[package]] name = "email-send" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "base64 0.13.1", "chirp-client", @@ -5537,7 +5537,7 @@ dependencies = [ [[package]] name = "email-verification-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5551,7 +5551,7 @@ dependencies = [ [[package]] name = "email-verification-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5685,7 +5685,7 @@ dependencies = [ [[package]] name = "external-request-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5701,7 +5701,7 @@ dependencies = [ [[package]] name = "external-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5715,7 +5715,7 @@ dependencies = [ [[package]] name = "faker-build" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "build-create", "chirp-client", @@ -5728,7 +5728,7 @@ dependencies = [ [[package]] name = "faker-cdn-site" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-site-create", "chirp-client", @@ -5742,7 +5742,7 @@ dependencies = [ [[package]] name = "faker-game" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5759,7 +5759,7 @@ dependencies = [ [[package]] name = "faker-game-namespace" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5772,7 +5772,7 @@ dependencies = [ [[package]] name = "faker-game-version" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5791,7 +5791,7 @@ dependencies = [ [[package]] name = "faker-job-run" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5805,7 +5805,7 @@ dependencies = [ [[package]] name = "faker-job-template" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5817,7 +5817,7 @@ dependencies = [ [[package]] name = "faker-mm-lobby" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5836,7 +5836,7 @@ dependencies = [ [[package]] name = "faker-mm-lobby-row" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5848,7 +5848,7 @@ dependencies = [ [[package]] name = "faker-mm-player" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5859,7 +5859,7 @@ dependencies = [ [[package]] name = "faker-region" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5872,7 +5872,7 @@ dependencies = [ [[package]] name = "faker-team" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -5884,7 +5884,7 @@ dependencies = [ [[package]] name = "faker-user" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6127,7 +6127,7 @@ dependencies = [ [[package]] name = "formatted-error" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "gray_matter", "hashbrown 0.12.3", @@ -6380,7 +6380,7 @@ dependencies = [ [[package]] name = "game-banner-upload-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6396,7 +6396,7 @@ dependencies = [ [[package]] name = "game-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6413,7 +6413,7 @@ dependencies = [ [[package]] name = "game-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6428,7 +6428,7 @@ dependencies = [ [[package]] name = "game-list-all" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6439,7 +6439,7 @@ dependencies = [ [[package]] name = "game-list-for-team" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6451,7 +6451,7 @@ dependencies = [ [[package]] name = "game-logo-upload-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6467,7 +6467,7 @@ dependencies = [ [[package]] name = "game-namespace-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6481,7 +6481,7 @@ dependencies = [ [[package]] name = "game-namespace-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6495,7 +6495,7 @@ dependencies = [ [[package]] name = "game-namespace-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6509,7 +6509,7 @@ dependencies = [ [[package]] name = "game-namespace-resolve-name-id" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6523,7 +6523,7 @@ dependencies = [ [[package]] name = "game-namespace-resolve-url" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-domain-create", "cdn-namespace-resolve-domain", @@ -6542,7 +6542,7 @@ dependencies = [ [[package]] name = "game-namespace-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6554,7 +6554,7 @@ dependencies = [ [[package]] name = "game-namespace-version-history-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6565,7 +6565,7 @@ dependencies = [ [[package]] name = "game-namespace-version-set" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6582,7 +6582,7 @@ dependencies = [ [[package]] name = "game-recommend" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6594,7 +6594,7 @@ dependencies = [ [[package]] name = "game-resolve-name-id" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6607,7 +6607,7 @@ dependencies = [ [[package]] name = "game-resolve-namespace-id" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6621,7 +6621,7 @@ dependencies = [ [[package]] name = "game-token-development-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6631,7 +6631,7 @@ dependencies = [ [[package]] name = "game-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6642,7 +6642,7 @@ dependencies = [ [[package]] name = "game-version-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6656,7 +6656,7 @@ dependencies = [ [[package]] name = "game-version-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6669,7 +6669,7 @@ dependencies = [ [[package]] name = "game-version-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6682,7 +6682,7 @@ dependencies = [ [[package]] name = "game-version-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -6777,7 +6777,7 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "global-error" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "async-trait", "formatted-error", @@ -7804,7 +7804,7 @@ dependencies = [ [[package]] name = "ip-info" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -7919,7 +7919,7 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "job-gc" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -7952,7 +7952,7 @@ dependencies = [ [[package]] name = "job-log-read" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -7965,7 +7965,7 @@ dependencies = [ [[package]] name = "job-log-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -7983,7 +7983,7 @@ dependencies = [ [[package]] name = "job-run" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8134,7 +8134,7 @@ dependencies = [ [[package]] name = "kv-str" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "envy", @@ -8292,7 +8292,7 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linode" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-workflow", "chrono", @@ -8309,7 +8309,7 @@ dependencies = [ [[package]] name = "linode-gc" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", @@ -8351,7 +8351,7 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "load-test-api-cloud" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8374,7 +8374,7 @@ dependencies = [ [[package]] name = "load-test-mm" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8405,7 +8405,7 @@ dependencies = [ [[package]] name = "load-test-mm-sustain" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8438,7 +8438,7 @@ dependencies = [ [[package]] name = "load-test-sqlx" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-get", "cdn-version-get", @@ -8460,7 +8460,7 @@ dependencies = [ [[package]] name = "load-test-watch-requests" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8733,7 +8733,7 @@ dependencies = [ [[package]] name = "mm-config-game-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8743,7 +8743,7 @@ dependencies = [ [[package]] name = "mm-config-game-upsert" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8753,7 +8753,7 @@ dependencies = [ [[package]] name = "mm-config-lobby-group-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8767,7 +8767,7 @@ dependencies = [ [[package]] name = "mm-config-lobby-group-resolve-name-id" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8783,7 +8783,7 @@ dependencies = [ [[package]] name = "mm-config-lobby-group-resolve-version" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8797,7 +8797,7 @@ dependencies = [ [[package]] name = "mm-config-namespace-config-set" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8811,7 +8811,7 @@ dependencies = [ [[package]] name = "mm-config-namespace-config-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8821,7 +8821,7 @@ dependencies = [ [[package]] name = "mm-config-namespace-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8832,7 +8832,7 @@ dependencies = [ [[package]] name = "mm-config-namespace-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8844,7 +8844,7 @@ dependencies = [ [[package]] name = "mm-config-version-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8861,7 +8861,7 @@ dependencies = [ [[package]] name = "mm-config-version-prepare" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "build-get", "chirp-client", @@ -8888,7 +8888,7 @@ dependencies = [ [[package]] name = "mm-config-version-publish" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8904,7 +8904,7 @@ dependencies = [ [[package]] name = "mm-dev-player-token-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8915,7 +8915,7 @@ dependencies = [ [[package]] name = "mm-gc" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8944,7 +8944,7 @@ dependencies = [ [[package]] name = "mm-lobby-find-fail" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8955,7 +8955,7 @@ dependencies = [ [[package]] name = "mm-lobby-find-lobby-query-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8966,7 +8966,7 @@ dependencies = [ [[package]] name = "mm-lobby-find-try-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8978,7 +8978,7 @@ dependencies = [ [[package]] name = "mm-lobby-for-run-id" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -8989,7 +8989,7 @@ dependencies = [ [[package]] name = "mm-lobby-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9002,7 +9002,7 @@ dependencies = [ [[package]] name = "mm-lobby-history" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9015,7 +9015,7 @@ dependencies = [ [[package]] name = "mm-lobby-idle-update" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9037,7 +9037,7 @@ dependencies = [ [[package]] name = "mm-lobby-list-for-namespace" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9050,7 +9050,7 @@ dependencies = [ [[package]] name = "mm-lobby-list-for-user-id" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9062,7 +9062,7 @@ dependencies = [ [[package]] name = "mm-lobby-player-count" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9075,7 +9075,7 @@ dependencies = [ [[package]] name = "mm-lobby-runtime-aggregate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9095,7 +9095,7 @@ dependencies = [ [[package]] name = "mm-lobby-state-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9108,7 +9108,7 @@ dependencies = [ [[package]] name = "mm-player-count-for-namespace" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9121,7 +9121,7 @@ dependencies = [ [[package]] name = "mm-player-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9133,7 +9133,7 @@ dependencies = [ [[package]] name = "mm-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "build-get", "chirp-client", @@ -9205,7 +9205,7 @@ checksum = "b52c1b33ff98142aecea13138bd399b68aa7ab5d9546c300988c345004001eea" [[package]] name = "monolith-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-worker", "cf-custom-hostname-worker", @@ -9233,7 +9233,7 @@ dependencies = [ [[package]] name = "monolith-workflow-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-workflow", "cluster", @@ -9454,7 +9454,7 @@ dependencies = [ [[package]] name = "nomad-monitor" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -9486,7 +9486,7 @@ dependencies = [ [[package]] name = "nomad-util" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "base64 0.13.1", "bytes", @@ -10107,7 +10107,7 @@ dependencies = [ [[package]] name = "pegboard" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-workflow", "lazy_static", @@ -10148,7 +10148,7 @@ dependencies = [ [[package]] name = "pegboard-config" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "pegboard", "schemars", @@ -10159,7 +10159,7 @@ dependencies = [ [[package]] name = "pegboard-container-runner" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "nix 0.27.1", @@ -10174,7 +10174,7 @@ dependencies = [ [[package]] name = "pegboard-dc-init" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -10203,7 +10203,7 @@ dependencies = [ [[package]] name = "pegboard-gc" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", @@ -10223,7 +10223,7 @@ dependencies = [ [[package]] name = "pegboard-isolate-v8-runner" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "deno_ast 0.42.2", @@ -10266,7 +10266,7 @@ dependencies = [ [[package]] name = "pegboard-manager" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "bytes", @@ -10304,7 +10304,7 @@ dependencies = [ [[package]] name = "pegboard-metrics-publish" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", @@ -10322,7 +10322,7 @@ dependencies = [ [[package]] name = "pegboard-ws" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", @@ -11159,7 +11159,7 @@ dependencies = [ [[package]] name = "redis-util" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "lazy_static", "redis", @@ -11267,7 +11267,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "region-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -11281,7 +11281,7 @@ dependencies = [ [[package]] name = "region-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -11295,7 +11295,7 @@ dependencies = [ [[package]] name = "region-list-for-game" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -11309,7 +11309,7 @@ dependencies = [ [[package]] name = "region-recommend" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -11324,7 +11324,7 @@ dependencies = [ [[package]] name = "region-resolve" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -11340,7 +11340,7 @@ dependencies = [ [[package]] name = "region-resolve-for-game" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -11517,7 +11517,7 @@ dependencies = [ [[package]] name = "rivet-actors-sdk-embed" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "deno-embed", @@ -11569,7 +11569,7 @@ dependencies = [ [[package]] name = "rivet-cache" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "futures-util", "global-error", @@ -11594,7 +11594,7 @@ dependencies = [ [[package]] name = "rivet-cache-result" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "rivet-util", ] @@ -11623,7 +11623,7 @@ dependencies = [ [[package]] name = "rivet-claims" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "base64 0.13.1", "global-error", @@ -11640,7 +11640,7 @@ dependencies = [ [[package]] name = "rivet-cli" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "async-posthog", @@ -11687,7 +11687,7 @@ dependencies = [ [[package]] name = "rivet-config" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "config", "dirs", @@ -11704,7 +11704,7 @@ dependencies = [ [[package]] name = "rivet-connection" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-perf", @@ -11717,7 +11717,7 @@ dependencies = [ [[package]] name = "rivet-convert" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "cdn-namespace-get", "chirp-client", @@ -11757,7 +11757,7 @@ dependencies = [ [[package]] name = "rivet-env" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "lazy_static", @@ -11789,7 +11789,7 @@ dependencies = [ [[package]] name = "rivet-health-checks" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "global-error", @@ -11806,7 +11806,7 @@ dependencies = [ [[package]] name = "rivet-hub-embed" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "include_dir", "reqwest 0.12.9", @@ -11850,7 +11850,7 @@ dependencies = [ [[package]] name = "rivet-job-runner" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "portpicker", @@ -11872,7 +11872,7 @@ dependencies = [ [[package]] name = "rivet-js-utils-embed" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "deno-embed", @@ -11931,7 +11931,7 @@ dependencies = [ [[package]] name = "rivet-metrics" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "global-error", "hyper 0.14.31", @@ -11945,7 +11945,7 @@ dependencies = [ [[package]] name = "rivet-migrate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "futures-util", @@ -11963,7 +11963,7 @@ dependencies = [ [[package]] name = "rivet-operation" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "async-trait", "chirp-client", @@ -11990,7 +11990,7 @@ dependencies = [ [[package]] name = "rivet-operation-macros" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "proc-macro2", "quote", @@ -12021,7 +12021,7 @@ dependencies = [ [[package]] name = "rivet-pools" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "async-nats", "clickhouse", @@ -12080,7 +12080,7 @@ dependencies = [ [[package]] name = "rivet-runtime" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "console-subscriber", "lazy_static", @@ -12094,7 +12094,7 @@ dependencies = [ [[package]] name = "rivet-schema-generator" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "pegboard-config", @@ -12106,7 +12106,7 @@ dependencies = [ [[package]] name = "rivet-server" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "api-monolith-edge", @@ -12171,7 +12171,7 @@ dependencies = [ [[package]] name = "rivet-service-manager" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "chrono", @@ -12223,21 +12223,21 @@ dependencies = [ [[package]] name = "rivet-test" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "types-proto", ] [[package]] name = "rivet-test-images" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "testcontainers", ] [[package]] name = "rivet-toolchain" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "anyhow", "assert_cmd", @@ -12291,7 +12291,7 @@ dependencies = [ [[package]] name = "rivet-util" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "async-trait", "bcrypt", @@ -12319,14 +12319,14 @@ dependencies = [ [[package]] name = "rivet-util-build" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "rivet-operation", ] [[package]] name = "rivet-util-captcha" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "global-error", "serde_json", @@ -12334,18 +12334,18 @@ dependencies = [ [[package]] name = "rivet-util-cdn" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" [[package]] name = "rivet-util-job" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "uuid", ] [[package]] name = "rivet-util-macros" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "proc-macro2", "quote", @@ -12354,7 +12354,7 @@ dependencies = [ [[package]] name = "rivet-util-mm" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "bit-vec", "chirp-client", @@ -12375,14 +12375,14 @@ dependencies = [ [[package]] name = "rivet-util-search" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "uuid", ] [[package]] name = "rivet-util-team" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "rivet-operation", ] @@ -12662,7 +12662,7 @@ checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5" [[package]] name = "s3-util" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "aws-sdk-s3", "aws-smithy-async 1.2.1", @@ -12716,7 +12716,7 @@ dependencies = [ [[package]] name = "schemac" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "lazy_static", "prost-build 0.11.9", @@ -13191,7 +13191,7 @@ dependencies = [ [[package]] name = "server-spec" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-workflow", "linode", @@ -14460,7 +14460,7 @@ dependencies = [ [[package]] name = "team-avatar-upload-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14476,7 +14476,7 @@ dependencies = [ [[package]] name = "team-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14489,7 +14489,7 @@ dependencies = [ [[package]] name = "team-invite-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14501,7 +14501,7 @@ dependencies = [ [[package]] name = "team-invite-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14517,7 +14517,7 @@ dependencies = [ [[package]] name = "team-join-request-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14528,7 +14528,7 @@ dependencies = [ [[package]] name = "team-member-count" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14539,7 +14539,7 @@ dependencies = [ [[package]] name = "team-member-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14550,7 +14550,7 @@ dependencies = [ [[package]] name = "team-member-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14561,7 +14561,7 @@ dependencies = [ [[package]] name = "team-member-relationship-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14573,7 +14573,7 @@ dependencies = [ [[package]] name = "team-profile-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14584,7 +14584,7 @@ dependencies = [ [[package]] name = "team-recommend" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14595,7 +14595,7 @@ dependencies = [ [[package]] name = "team-resolve-display-name" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14608,7 +14608,7 @@ dependencies = [ [[package]] name = "team-user-ban-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14619,7 +14619,7 @@ dependencies = [ [[package]] name = "team-user-ban-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14630,7 +14630,7 @@ dependencies = [ [[package]] name = "team-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14641,7 +14641,7 @@ dependencies = [ [[package]] name = "team-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14663,7 +14663,7 @@ dependencies = [ [[package]] name = "telemetry-beacon" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "async-posthog", "chirp-client", @@ -14812,7 +14812,7 @@ dependencies = [ [[package]] name = "tier" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-workflow", "cluster", @@ -14904,7 +14904,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "token-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "base64 0.13.1", "chirp-client", @@ -14920,7 +14920,7 @@ dependencies = [ [[package]] name = "token-exchange" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14933,7 +14933,7 @@ dependencies = [ [[package]] name = "token-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -14946,7 +14946,7 @@ dependencies = [ [[package]] name = "token-revoke" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15572,7 +15572,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types-proto" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-types", "http 0.2.12", @@ -15587,7 +15587,7 @@ dependencies = [ [[package]] name = "types-proto-build" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "heck 0.3.3", "indoc 1.0.9", @@ -15765,7 +15765,7 @@ dependencies = [ [[package]] name = "upload-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15782,7 +15782,7 @@ dependencies = [ [[package]] name = "upload-file-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15794,7 +15794,7 @@ dependencies = [ [[package]] name = "upload-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15807,7 +15807,7 @@ dependencies = [ [[package]] name = "upload-list-for-user" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15820,7 +15820,7 @@ dependencies = [ [[package]] name = "upload-prepare" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15837,7 +15837,7 @@ dependencies = [ [[package]] name = "upload-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15900,12 +15900,15 @@ dependencies = [ [[package]] name = "user" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-workflow", "cluster", "email-address-parser", + "faker-user", "linode", + "rand", + "reqwest 0.11.27", "rivet-config", "rivet-operation", "serde", @@ -15915,12 +15918,12 @@ dependencies = [ "upload-complete", "upload-file-list", "upload-get", - "user-identity-get", + "upload-prepare", ] [[package]] name = "user-avatar-upload-complete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15936,7 +15939,7 @@ dependencies = [ [[package]] name = "user-delete-pending" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15958,7 +15961,7 @@ dependencies = [ [[package]] name = "user-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15973,7 +15976,7 @@ dependencies = [ [[package]] name = "user-identity-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15985,7 +15988,7 @@ dependencies = [ [[package]] name = "user-identity-delete" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -15998,7 +16001,7 @@ dependencies = [ [[package]] name = "user-identity-get" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -16013,7 +16016,7 @@ dependencies = [ [[package]] name = "user-pending-delete-toggle" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -16027,7 +16030,7 @@ dependencies = [ [[package]] name = "user-profile-validate" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -16041,7 +16044,7 @@ dependencies = [ [[package]] name = "user-resolve-email" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -16054,7 +16057,7 @@ dependencies = [ [[package]] name = "user-team-list" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -16065,7 +16068,7 @@ dependencies = [ [[package]] name = "user-token-create" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -16078,7 +16081,7 @@ dependencies = [ [[package]] name = "user-worker" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -16099,7 +16102,6 @@ dependencies = [ "upload-list-for-user", "upload-prepare", "user", - "user-identity-delete", ] [[package]] @@ -17014,7 +17016,7 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "workflow-gc" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-worker", @@ -17032,7 +17034,7 @@ dependencies = [ [[package]] name = "workflow-metrics-publish" -version = "24.6.2-rc.1" +version = "25.1.0-rc.1" dependencies = [ "chirp-client", "chirp-workflow", diff --git a/packages/api/cloud/src/auth.rs b/packages/api/cloud/src/auth.rs index eb836c93a7..772e35f94a 100644 --- a/packages/api/cloud/src/auth.rs +++ b/packages/api/cloud/src/auth.rs @@ -296,7 +296,7 @@ impl Auth { team_ids: team_ids .iter() .map(|id| (*id).into()) - .collect::>() + .collect::>() }) .await?; diff --git a/packages/api/group/tests/basic.rs b/packages/api/group/tests/basic.rs index d280ddc85c..f039638697 100644 --- a/packages/api/group/tests/basic.rs +++ b/packages/api/group/tests/basic.rs @@ -61,7 +61,7 @@ impl Ctx { let token_res = chirp_workflow::compat::op( &ctx, - user::ops::token_create::get::Input { + ::user::ops::token_create::Input { user_id: user_id, client: backend::net::ClientInfo { user_agent: Some(USER_AGENT.into()), diff --git a/packages/api/portal/tests/basic.rs b/packages/api/portal/tests/basic.rs index 80e1c8e792..6e55f00144 100644 --- a/packages/api/portal/tests/basic.rs +++ b/packages/api/portal/tests/basic.rs @@ -60,7 +60,7 @@ impl Ctx { let token_res = chirp_workflow::compat::op( &ctx, - user::ops::token_create::get::Input { + ::user::ops::token_create::Input { user_id: user_id, client: backend::net::ClientInfo { user_agent: Some(USER_AGENT.into()), diff --git a/packages/infra/server/src/run_config.rs b/packages/infra/server/src/run_config.rs index 2d0c403e1a..b957d1ad72 100644 --- a/packages/infra/server/src/run_config.rs +++ b/packages/infra/server/src/run_config.rs @@ -282,7 +282,7 @@ pub fn config(rivet_config: rivet_config::Config) -> Result { SqlService { kind: SqlServiceKind::CockroachDB, migrations: include_dir!( - "$CARGO_MANIFEST_DIR/../../services/user-identity/db/user-identity" + "$CARGO_MANIFEST_DIR/../../services/user/db/user-identity" ), db_name: "db_user_identity", }, diff --git a/packages/services/user/Cargo.toml b/packages/services/user/Cargo.toml index 8406ec5a71..b1329396cd 100644 --- a/packages/services/user/Cargo.toml +++ b/packages/services/user/Cargo.toml @@ -19,8 +19,14 @@ token-create.workspace = true upload-file-list.workspace = true upload-get.workspace = true upload-complete.workspace = true -user-identity-get.workspace = true [dependencies.sqlx] workspace = true -default-features = false \ No newline at end of file +default-features = false + +[dev-dependencies] +faker-user.workspace = true +rand = "0.8" +reqwest = "0.11" +upload-get.workspace = true +upload-prepare.workspace = true \ No newline at end of file diff --git a/packages/services/user/db/user/migrations/20200101000001_init.down.sql b/packages/services/user/db/user-identity/migrations/20200101000000_init.down.sql similarity index 100% rename from packages/services/user/db/user/migrations/20200101000001_init.down.sql rename to packages/services/user/db/user-identity/migrations/20200101000000_init.down.sql diff --git a/packages/services/user/db/user/migrations/20200101000001_init.up.sql b/packages/services/user/db/user-identity/migrations/20200101000000_init.up.sql similarity index 100% rename from packages/services/user/db/user/migrations/20200101000001_init.up.sql rename to packages/services/user/db/user-identity/migrations/20200101000000_init.up.sql diff --git a/packages/services/user/db/user/migrations/20230101105612_index_user.down.sql b/packages/services/user/db/user-identity/migrations/20230101105612_index_user.down.sql similarity index 100% rename from packages/services/user/db/user/migrations/20230101105612_index_user.down.sql rename to packages/services/user/db/user-identity/migrations/20230101105612_index_user.down.sql diff --git a/packages/services/user/db/user/migrations/20230101105612_index_user.up.sql b/packages/services/user/db/user-identity/migrations/20230101105612_index_user.up.sql similarity index 100% rename from packages/services/user/db/user/migrations/20230101105612_index_user.up.sql rename to packages/services/user/db/user-identity/migrations/20230101105612_index_user.up.sql diff --git a/packages/services/user/db/user/migrations/20231116005712_access_tokens.down.sql b/packages/services/user/db/user-identity/migrations/20231116005712_access_tokens.down.sql similarity index 100% rename from packages/services/user/db/user/migrations/20231116005712_access_tokens.down.sql rename to packages/services/user/db/user-identity/migrations/20231116005712_access_tokens.down.sql diff --git a/packages/services/user/db/user/migrations/20231116005712_access_tokens.up.sql b/packages/services/user/db/user-identity/migrations/20231116005712_access_tokens.up.sql similarity index 100% rename from packages/services/user/db/user/migrations/20231116005712_access_tokens.up.sql rename to packages/services/user/db/user-identity/migrations/20231116005712_access_tokens.up.sql diff --git a/packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.down.sql b/packages/services/user/db/user-identity/migrations/20241104000750_drop_access_tokens.down.sql similarity index 100% rename from packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.down.sql rename to packages/services/user/db/user-identity/migrations/20241104000750_drop_access_tokens.down.sql diff --git a/packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.up.sql b/packages/services/user/db/user-identity/migrations/20241104000750_drop_access_tokens.up.sql similarity index 100% rename from packages/services/user/db/user/migrations/20241104000750_drop_access_tokens.up.sql rename to packages/services/user/db/user-identity/migrations/20241104000750_drop_access_tokens.up.sql diff --git a/packages/services/user/tests/avatar_upload_complete.rs b/packages/services/user/tests/avatar_upload_complete.rs new file mode 100644 index 0000000000..37caf9abc8 --- /dev/null +++ b/packages/services/user/tests/avatar_upload_complete.rs @@ -0,0 +1,62 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto::backend; + +const TEST_BODY: &[u8] = b"test file"; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_res = op!([ctx] faker_user {}).await.unwrap(); + let user_id = user_res.user_id.unwrap().as_uuid(); + + // Create the upload + let upload_prepare_res = op!([ctx] upload_prepare { + bucket: "bucket-user-avatar".into(), + files: vec![ + backend::upload::PrepareFile { + path: "image.png".to_owned(), + mime: Some("image/png".into()), + content_length: TEST_BODY.len() as u64, + ..Default::default() + }, + ], + }) + .await + .unwrap(); + let upload_id = upload_prepare_res.upload_id.unwrap(); + let presigned_request = upload_prepare_res.presigned_requests.first().unwrap(); + + tracing::info!("writing test files"); + let res = reqwest::Client::new() + .put(&presigned_request.url) + .body(TEST_BODY.to_vec()) + .header("content-type", "image/png") + .send() + .await + .expect("failed to upload"); + if res.status().is_success() { + tracing::info!("uploaded successfully"); + } else { + panic!( + "failed to upload ({}): {:?}", + res.status(), + res.text().await + ); + } + + ctx.op(::user::ops::avatar_upload_complete::Input { + user_id: user_id, + upload_id: upload_id.as_uuid() + }) + .await + .unwrap(); + + let uploads_res = op!([ctx] upload_get { + upload_ids: vec![upload_id] + }) + .await + .unwrap(); + + let upload = uploads_res.uploads.first().unwrap(); + + assert!(upload.complete_ts.is_some(), "Upload did not complete"); +} diff --git a/packages/services/user/tests/get.rs b/packages/services/user/tests/get.rs new file mode 100644 index 0000000000..ab54e6d194 --- /dev/null +++ b/packages/services/user/tests/get.rs @@ -0,0 +1,72 @@ +use chirp_workflow::prelude::*; +use proto::backend::{pkg::*}; +use rivet_operation::prelude::proto; +use rand::Rng; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let res = ctx.op(::user::ops::get::Input { + user_ids: Vec::new(), + }) + .await + .unwrap(); + assert!(res.users.is_empty()); +} + +#[workflow_test] +async fn fetch(ctx: TestCtx) { + struct TestUser { + user_id: Option, + display_name: String, + account_number: i64, + bio: String, + } + + // Generate test users + let mut users = std::iter::repeat_with(|| TestUser { + user_id: None, + display_name: util::faker::display_name(), + account_number: rand::thread_rng().gen_range(1..10000), + bio: util::faker::ident(), + }) + .take(8) + .collect::>(); + + // Insert test users + for user in &mut users { + let user_res = op!([ctx] faker_user { }).await.unwrap(); + let user_id = user_res.user_id.unwrap().as_uuid(); + + msg!([ctx] user::msg::profile_set(user_id) -> user::msg::update { + user_id: Some(user_id.into()), + display_name: Some(user.display_name.clone()), + account_number: Some(user.account_number as u32), + bio: Some(user.bio.clone()), + }) + .await + .unwrap(); + + user.user_id = Some(user_id); + } + + // Fetch the users + let res = ctx.op(::user::ops::get::Input { + user_ids: users.iter().map(|u| u.user_id.unwrap()).collect(), + }) + .await + .unwrap(); + + // Validate the users + assert_eq!(users.len(), res.users.len()); + for user in &users { + let user_res = res + .users + .iter() + .find(|u| u.user_id.unwrap().as_uuid() == user.user_id.unwrap()) + .expect("user not returned"); + + assert_eq!(user.display_name, user_res.display_name); + assert_eq!(user.account_number, user_res.account_number as i64); + assert_eq!(user.bio, user_res.bio); + } +} diff --git a/packages/services/user/tests/identity_create.rs b/packages/services/user/tests/identity_create.rs new file mode 100644 index 0000000000..d133afb077 --- /dev/null +++ b/packages/services/user/tests/identity_create.rs @@ -0,0 +1,35 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto::backend; + +#[workflow_test] +async fn email(ctx: TestCtx) { + let user_res = op!([ctx] faker_user { + ..Default::default() + }) + .await + .unwrap(); + let user_id = user_res.user_id.unwrap().as_uuid(); + + let email = util::faker::email(); + ctx.op(::user::ops::identity::create::Input { + user_id: user_id, + identity: backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email( + backend::user_identity::identity::Email { + email: email.clone(), + } + )), + }, + }) + .await + .unwrap(); + + let (sql_exists,) = sqlx::query_as::<_, (bool,)>( + "SELECT EXISTS (SELECT 1 FROM db_user_identity.emails WHERE email = $1)", + ) + .bind(&email) + .fetch_one(&ctx.crdb().await.unwrap()) + .await + .unwrap(); + assert!(sql_exists, "identity not created"); +} diff --git a/packages/services/user/tests/identity_delete.rs b/packages/services/user/tests/identity_delete.rs new file mode 100644 index 0000000000..fb60977b58 --- /dev/null +++ b/packages/services/user/tests/identity_delete.rs @@ -0,0 +1,41 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto::backend; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_res = op!([ctx] faker_user { + ..Default::default() + }) + .await + .unwrap(); + let user_id = user_res.user_id.unwrap().as_uuid(); + + let email = util::faker::email(); + ctx.op(::user::ops::identity::create::Input { + user_id: user_id, + identity: backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email( + backend::user_identity::identity::Email { + email: email.clone() + } + )), + }, + }) + .await + .unwrap(); + + ctx.op(::user::ops::identity::delete::Input { + user_ids: vec![user_id], + }) + .await + .unwrap(); + + let (sql_exists,) = sqlx::query_as::<_, (bool,)>( + "SELECT EXISTS (SELECT 1 FROM db_user_identity.emails WHERE email = $1)", + ) + .bind(&email) + .fetch_one(&ctx.crdb().await.unwrap()) + .await + .unwrap(); + assert!(!sql_exists, "identity not deleted"); +} diff --git a/packages/services/user/tests/identity_get.rs b/packages/services/user/tests/identity_get.rs new file mode 100644 index 0000000000..cae9379a9c --- /dev/null +++ b/packages/services/user/tests/identity_get.rs @@ -0,0 +1,42 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto::backend; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_res = op!([ctx] faker_user { + ..Default::default() + }) + .await + .unwrap(); + let user_id = user_res.user_id.unwrap().as_uuid(); + + let email = util::faker::email(); + ctx.op(::user::ops::identity::create::Input { + user_id: user_id, + identity: backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email( + backend::user_identity::identity::Email { + email: email.clone() + } + )), + }, + }) + .await + .unwrap(); + + let res = ctx.op(::user::ops::identity::get::Input { + user_ids: vec![user_id, Uuid::new_v4()], + }) + .await + .unwrap(); + assert_eq!(1, res.users.len()); + assert_eq!( + 1, + res.users + .iter() + .find(|u| u.user_id == user_id) + .unwrap() + .identities + .len() + ); +} diff --git a/packages/services/user/tests/pending_delete_toggle.rs b/packages/services/user/tests/pending_delete_toggle.rs new file mode 100644 index 0000000000..c992d388d0 --- /dev/null +++ b/packages/services/user/tests/pending_delete_toggle.rs @@ -0,0 +1,67 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto::backend; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_res = op!([ctx] faker_user {}).await.unwrap(); + let user_id = user_res.user_id.as_ref().unwrap().as_uuid(); + + // Register user + let email = util::faker::email(); + let _res = ctx.op(::user::ops::identity::create::Input { + user_id: user_id, + identity: backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email( + backend::user_identity::identity::Email { + email: email.clone() + } + )), + }, + }) + .await + .unwrap(); + + ctx.op(::user::ops::pending_delete_toggle::Input { + user_id: user_id, + active: true, + }) + .await + .unwrap(); + + let (delete_request_ts,): (Option,) = sqlx::query_as(indoc!( + " + SELECT delete_request_ts + FROM db_user.users + WHERE + user_id = $1 + ", + )) + .bind(user_id) + .fetch_one(&ctx.crdb().await.unwrap()) + .await + .unwrap(); + + assert!(delete_request_ts.is_some()); + + ctx.op(::user::ops::pending_delete_toggle::Input { + user_id: user_id, + active: false, + }) + .await + .unwrap(); + + let (delete_request_ts,): (Option,) = sqlx::query_as(indoc!( + " + SELECT delete_request_ts + FROM db_user.users + WHERE + user_id = $1 + ", + )) + .bind(user_id) + .fetch_one(&ctx.crdb().await.unwrap()) + .await + .unwrap(); + + assert!(delete_request_ts.is_none()); +} diff --git a/packages/services/user/tests/profile_validate.rs b/packages/services/user/tests/profile_validate.rs new file mode 100644 index 0000000000..205039102d --- /dev/null +++ b/packages/services/user/tests/profile_validate.rs @@ -0,0 +1,18 @@ +use chirp_workflow::prelude::*; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_res = op!([ctx] faker_user {}).await.unwrap(); + let user_id = user_res.user_id.unwrap().as_uuid(); + + let res = ctx.op(::user::ops::profile_validate::Input { + user_id: user_id, + display_name: Some(" bad display name".to_owned()), + account_number: Some(10000), + bio: Some("bad\n\n\n\n\n\nbio".to_owned()) + }) + .await + .unwrap(); + + assert_eq!(res.errors.len(), 3, "validation failed"); +} diff --git a/packages/services/user/tests/resolve_email.rs b/packages/services/user/tests/resolve_email.rs new file mode 100644 index 0000000000..5a82efed89 --- /dev/null +++ b/packages/services/user/tests/resolve_email.rs @@ -0,0 +1,35 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto::backend; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_res = op!([ctx] faker_user { + ..Default::default() + }) + .await + .unwrap(); + let user_id = user_res.user_id.as_ref().unwrap().as_uuid(); + + let email = util::faker::email(); + ctx.op(::user::ops::identity::create::Input { + user_id: user_id, + identity: backend::user_identity::Identity { + kind: Some(backend::user_identity::identity::Kind::Email( + backend::user_identity::identity::Email { + email: email.clone() + } + )), + }, + }) + .await + .unwrap(); + + let res = ctx.op(::user::ops::resolve_email::Input { + emails: vec![email.clone(), util::faker::email()], + }) + .await + .unwrap(); + assert_eq!(1, res.users.len()); + let user = res.users.first().unwrap(); + assert_eq!(user_id, user.user_id); +} diff --git a/packages/services/user/tests/team_list.rs b/packages/services/user/tests/team_list.rs new file mode 100644 index 0000000000..00b18e682f --- /dev/null +++ b/packages/services/user/tests/team_list.rs @@ -0,0 +1,49 @@ +use std::collections::HashMap; + +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto; +use proto::backend::{pkg::*}; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_a = Uuid::new_v4(); + let user_b = Uuid::new_v4(); + let user_c = Uuid::new_v4(); + + let team_a = Uuid::new_v4(); + let team_b = Uuid::new_v4(); + let team_c = Uuid::new_v4(); + + let members = vec![ + (user_a, team_a), + (user_a, team_b), + (user_b, team_a), + (user_b, team_b), + (user_b, team_c), + ]; + for (user_id, team_id) in &members { + msg!([ctx] team::msg::member_create(team_id, user_id) -> team::msg::member_create_complete { + team_id: Some((*team_id).into()), + user_id: Some((*user_id).into()), + invitation: None, + }) + .await + .unwrap(); + } + + let res = ctx.op(::user::ops::team_list::Input { + user_ids: vec![user_a, user_b, user_c], + }) + .await + .unwrap(); + + assert_eq!(3, res.users.len()); + let users_map = res + .users + .iter() + .map(|u| (u.user_id, u.teams.len())) + .collect::>(); + assert_eq!(2, *users_map.get(&user_a).unwrap()); + assert_eq!(3, *users_map.get(&user_b).unwrap()); + assert_eq!(0, *users_map.get(&user_c).unwrap()); +} diff --git a/packages/services/user/tests/token_create.rs b/packages/services/user/tests/token_create.rs new file mode 100644 index 0000000000..f8bdb387a8 --- /dev/null +++ b/packages/services/user/tests/token_create.rs @@ -0,0 +1,18 @@ +use chirp_workflow::prelude::*; +use rivet_operation::prelude::proto::backend; + +#[workflow_test] +async fn empty(ctx: TestCtx) { + let user_res = op!([ctx] faker_user {}).await.unwrap(); + let user_id = user_res.user_id.as_ref().unwrap().as_uuid(); + + let res = ctx.op(::user::ops::token_create::Input { + user_id: user_id, + client: backend::net::ClientInfo::default() + }) + .await + .unwrap(); + + assert!(res.token.starts_with("usr")); + assert!(res.refresh_token.starts_with("usr_rf")); +}