Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions migrations/20260831100133_user-metadata-private.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_metadata ADD COLUMN private BOOL DEFAULT false;
8 changes: 6 additions & 2 deletions src/db/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct UserMetadata {
pub mantle_user_id: Uuid,
pub key: String,
pub value: serde_json::Value,
pub private: bool,

pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
Expand All @@ -18,20 +19,23 @@ pub async fn set(
mantle_user_id: Uuid,
key: &str,
value: &serde_json::Value,
private: Option<bool>,
) -> sqlx::Result<UserMetadata> {
sqlx::query_as(
r#"
INSERT INTO user_metadata (mantle_user_id, key, value)
VALUES ($1, $2, $3)
INSERT INTO user_metadata (mantle_user_id, key, value, private)
VALUES ($1, $2, $3, $4)
ON CONFLICT (mantle_user_id, key) DO UPDATE
SET value = excluded.value,
private = excluded.private,
updated_at = NOW()
RETURNING *;
"#,
)
.bind(mantle_user_id)
.bind(key)
.bind(value)
.bind(private.unwrap_or(false))
.fetch_one(d)
.await
}
Expand Down
3 changes: 2 additions & 1 deletion src/services/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl AccountService {
provider_user_id: &str,
key: &str,
value: &serde_json::Value,
private: Option<bool>,
) -> Result<UserMetadata> {
let identity = db::identities::find_by_provider_id(&self.db, provider, provider_user_id)
.await
Expand All @@ -116,7 +117,7 @@ impl AccountService {
provider_user_id: provider_user_id.into(),
})?;

let metadata = db::metadata::set(&self.db, identity.mantle_user_id, key, value)
let metadata = db::metadata::set(&self.db, identity.mantle_user_id, key, value, private)
.await
.map_err(InternalError::from)?;

Expand Down
8 changes: 8 additions & 0 deletions src/web/dto/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use serde::Deserialize;

#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
#[derive(Debug, Deserialize)]
pub struct MetadataRequestBody {
pub value: serde_json::Value,
pub private: Option<bool>,
}
1 change: 1 addition & 0 deletions src/web/dto/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod account;
pub mod auth;
pub mod health;

Expand Down
2 changes: 2 additions & 0 deletions src/web/dto/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ impl From<Identity> for IdentityDto {
#[derive(Debug, Serialize, Deserialize)]
pub struct UserMetadataDto {
value: serde_json::Value,
private: bool,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
}
Expand All @@ -41,6 +42,7 @@ impl From<UserMetadata> for UserMetadataDto {
fn from(value: UserMetadata) -> Self {
Self {
value: value.value,
private: value.private,
created_at: value.created_at,
updated_at: value.updated_at,
}
Expand Down
9 changes: 5 additions & 4 deletions src/web/routes/account.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::web::dto::account::*;
use crate::web::dto::{IdentityDto, UserMetadataDto, UserRequestQuery};
use crate::{
state::AppState,
Expand Down Expand Up @@ -66,8 +67,8 @@ async fn get_linked_identities(
("key" = String, Path, description = "Metadata key to set")
),
request_body(
content = serde_json::Value,
description = "Any JSON value to make metadata value",
content = MetadataRequestBody,
description = "Any JSON value to make metadata value and a private flag",
),
responses(
(status = 200, body = UserMetadataDto),
Expand All @@ -80,12 +81,12 @@ async fn set_metadata(
State(state): State<AppState>,
Query(req): Query<UserRequestQuery>,
Path(key): Path<String>,
Json(value): Json<serde_json::Value>,
Json(body): Json<MetadataRequestBody>,
) -> RouteResult<impl IntoResponse> {
let metadata = UserMetadataDto::from(
state
.account
.metadata_set(req.provider, &req.id, &key, &value)
.metadata_set(req.provider, &req.id, &key, &body.value, body.private)
.await?,
);
Ok((StatusCode::OK, Json(metadata)))
Expand Down
Loading