diff --git a/v-api/src/endpoints/api_user.rs b/v-api/src/endpoints/api_user.rs index 9718953..baad284 100644 --- a/v-api/src/endpoints/api_user.rs +++ b/v-api/src/endpoints/api_user.rs @@ -19,7 +19,8 @@ use uuid::Uuid; use v_model::{ permissions::{Caller, Permission, PermissionStorage, Permissions}, storage::{ApiUserProviderFilter, ListPagination}, - AccessGroupId, ApiKeyId, ApiUser, ApiUserProvider, NewApiKey, NewApiUser, UserId, + AccessGroupId, ApiKeyId, ApiUser, ApiUserContactEmail, ApiUserProvider, NewApiKey, NewApiUser, + UserId, }; use crate::{ @@ -245,6 +246,46 @@ where )) } +#[derive(Debug, Clone, Deserialize, JsonSchema)] +pub struct ApiUserEmailUpdateParams { + email: String, +} + +#[instrument(skip(rqctx, body), err(Debug))] +pub async fn set_api_user_contact_email_op( + rqctx: &RequestContext>, + path: ApiUserPath, + body: ApiUserEmailUpdateParams, +) -> Result, HttpError> +where + T: VAppPermission + PermissionStorage, +{ + let (ctx, caller) = rqctx.as_ctx().await?; + set_api_user_contact_email_inner(ctx, caller, path, body).await +} + +#[instrument(skip(ctx, body))] +pub async fn set_api_user_contact_email_inner( + ctx: &VContext, + caller: Caller, + path: ApiUserPath, + body: ApiUserEmailUpdateParams, +) -> Result, HttpError> +where + T: VAppPermission + PermissionStorage, +{ + tracing::info!("Setting contact email for user"); + + let email = ctx + .user + .set_api_user_contact_email(&caller, path.user_id, &body.email) + .await?; + + tracing::info!("Set contact email for user"); + + Ok(HttpResponseOk(email)) +} + #[derive(Debug, Clone, Deserialize, JsonSchema)] pub struct ApiKeyCreateParams { permissions: Option>, diff --git a/v-api/src/endpoints/handlers.rs b/v-api/src/endpoints/handlers.rs index a2210aa..4ea1569 100644 --- a/v-api/src/endpoints/handlers.rs +++ b/v-api/src/endpoints/handlers.rs @@ -13,16 +13,16 @@ mod macros { RequestContext, TypedBody, Body, }; use http::Response; - use v_model::{Mapper, OAuthClient, OAuthClientRedirectUri, OAuthClientSecret, AccessGroup, ApiUser, MagicLink, MagicLinkRedirectUri, MagicLinkSecret}; + use v_model::{Mapper, ApiUserContactEmail, OAuthClient, OAuthClientRedirectUri, OAuthClientSecret, AccessGroup, ApiUser, MagicLink, MagicLinkRedirectUri, MagicLinkSecret}; use v_api::endpoints::{ api_user::{ add_api_user_to_group_op, create_api_user_op, create_api_user_token_op, delete_api_user_token_op, get_api_user_op, get_api_user_token_op, get_self_op, - link_provider_op, list_api_user_tokens_op, remove_api_user_from_group_op, + link_provider_op, list_api_user_tokens_op, remove_api_user_from_group_op, set_api_user_contact_email_op, update_api_user_op, AddGroupBody, ApiKeyCreateParams, ApiKeyResponse, ApiUserPath, ApiUserProviderLinkPayload, ApiUserRemoveGroupPath, ApiUserTokenPath, - ApiUserUpdateParams, GetUserResponse, InitialApiKeyResponse, + ApiUserUpdateParams, GetUserResponse, InitialApiKeyResponse, ApiUserEmailUpdateParams }, api_user_provider::{ create_link_token_op, ApiUserLinkRequestPayload, ApiUserLinkRequestResponse, @@ -492,6 +492,19 @@ mod macros { delete_api_user_token_op(&rqctx, path.into_inner()).await } + /// Set the contact email for a user + #[endpoint { + method = PUT, + path = "/api-user/{user_id}/contact/email", + }] + pub async fn set_api_user_contact_email( + rqctx: RequestContext<$context_type>, + path: Path, + body: TypedBody, + ) -> Result, HttpError> { + set_api_user_contact_email_op(&rqctx, path.into_inner(), body.into_inner()).await + } + /// Add a user to a group #[endpoint { method = POST, @@ -654,6 +667,8 @@ mod macros { .expect("Failed to register endpoint"); $api.register(update_api_user) .expect("Failed to register endpoint"); + $api.register(set_api_user_contact_email) + .expect("Failed to register endpoint"); $api.register(list_api_user_tokens) .expect("Failed to register endpoint"); $api.register(get_api_user_token)