From 797ec2ec3ca9de86e2b1db1f75997fb1a3867f52 Mon Sep 17 00:00:00 2001 From: Sychic <47618543+Sychic@users.noreply.github.com> Date: Fri, 21 Aug 2026 14:30:11 -0400 Subject: [PATCH] fix(labrinth): disclosure visibility (#7265) --- .../ui/project-settings/disclosures/form.ts | 2 +- apps/labrinth/src/models/v3/disclosures.rs | 20 +++++++++++-------- apps/labrinth/src/routes/v3/disclosures.rs | 11 +++++++--- .../api-client/src/modules/labrinth/types.ts | 4 ++-- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/form.ts b/apps/frontend/src/components/ui/project-settings/disclosures/form.ts index 0e7d7324a9..d6cedf831a 100644 --- a/apps/frontend/src/components/ui/project-settings/disclosures/form.ts +++ b/apps/frontend/src/components/ui/project-settings/disclosures/form.ts @@ -47,7 +47,7 @@ function createLockStatuses( ) as Record for (const disclosure of disclosures) { - lockStatuses[disclosure.type] = disclosure.lock_status + lockStatuses[disclosure.type] = disclosure.lock_status ?? 'unlocked' } return lockStatuses diff --git a/apps/labrinth/src/models/v3/disclosures.rs b/apps/labrinth/src/models/v3/disclosures.rs index 52f6c06187..2c7e7b2a45 100644 --- a/apps/labrinth/src/models/v3/disclosures.rs +++ b/apps/labrinth/src/models/v3/disclosures.rs @@ -111,8 +111,10 @@ impl DisclosureLockStatus { pub struct ProjectDisclosureData { #[serde(flatten)] pub disclosure: ProjectDisclosure, - pub set_by_moderator: bool, - pub lock_status: DisclosureLockStatus, + #[serde(skip_serializing_if = "Option::is_none")] + pub set_by_moderator: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub lock_status: Option, pub updated_at: DateTime, #[serde(skip_serializing_if = "Option::is_none")] pub updated_by: Option, @@ -124,16 +126,18 @@ impl ProjectDisclosureData { pub fn from_db( value: DBProjectDisclosure, viewer_is_moderator: bool, + viewer_is_member: bool, ) -> Self { - let updated_by = (!value.set_by_moderator || viewer_is_moderator) - .then_some(value.updated_by.into()); - Self { disclosure: value.disclosure, - set_by_moderator: value.set_by_moderator, - lock_status: value.lock_status, + set_by_moderator: (viewer_is_member || viewer_is_moderator) + .then_some(value.set_by_moderator), + lock_status: (viewer_is_member || viewer_is_moderator) + .then_some(value.lock_status), updated_at: value.updated_at, - updated_by, + updated_by: ((!value.set_by_moderator && viewer_is_member) + || viewer_is_moderator) + .then_some(value.updated_by.into()), deleted_at: value.deleted_at, } } diff --git a/apps/labrinth/src/routes/v3/disclosures.rs b/apps/labrinth/src/routes/v3/disclosures.rs index 3c790c703d..b81fefdd32 100644 --- a/apps/labrinth/src/routes/v3/disclosures.rs +++ b/apps/labrinth/src/routes/v3/disclosures.rs @@ -73,14 +73,15 @@ pub async fn get_project_disclosures( let viewer_is_moderator = user_option.as_ref().is_some_and(|user| user.role.is_mod()); - let include_deleted = viewer_is_moderator + // Moderators can see regardless of membership, short circuit to avoid extra db call + let viewer_is_member = viewer_is_moderator || is_team_member_project(&project.inner, &user_option, &pool) .await .wrap_internal_err("failed to check project team membership")?; let disclosures = db_models::DBProjectDisclosure::get_many_for_project( project.inner.id, - include_deleted, + viewer_is_moderator || viewer_is_member, &***ro_pool, ) .await @@ -90,7 +91,11 @@ pub async fn get_project_disclosures( disclosures: disclosures .into_iter() .map(|disclosure| { - ProjectDisclosureData::from_db(disclosure, viewer_is_moderator) + ProjectDisclosureData::from_db( + disclosure, + viewer_is_moderator, + viewer_is_member, + ) }) .collect(), })) diff --git a/packages/api-client/src/modules/labrinth/types.ts b/packages/api-client/src/modules/labrinth/types.ts index 20e94d2ad6..0c7f1b48ce 100644 --- a/packages/api-client/src/modules/labrinth/types.ts +++ b/packages/api-client/src/modules/labrinth/types.ts @@ -1352,8 +1352,8 @@ export namespace Labrinth { } export type ProjectDisclosureData = ProjectDisclosure & { - set_by_moderator: boolean - lock_status: DisclosureLockStatus + set_by_moderator?: boolean | null + lock_status?: DisclosureLockStatus | null updated_at: string updated_by?: string | null deleted_at?: string | null