From c300a7a8cd02f0a927ea3cc7c02103ea23410107 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 18 Nov 2024 11:56:55 +0100 Subject: [PATCH] Do not allow leaving __world__ group --- src/sidebar/helpers/groups.ts | 10 ++++++-- src/sidebar/helpers/test/groups-test.js | 34 +++++++++++++++++++++++++ src/sidebar/services/groups.ts | 10 ++++---- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/sidebar/helpers/groups.ts b/src/sidebar/helpers/groups.ts index ecf0eb979f4..4a246534f39 100644 --- a/src/sidebar/helpers/groups.ts +++ b/src/sidebar/helpers/groups.ts @@ -18,6 +18,8 @@ function allowLeavingGroups(settings: SidebarSettings): boolean { return !!config.allowLeavingGroups; } +export const PUBLIC_GROUP_ID = '__world__'; + /** * Combine groups from multiple api calls together to form a unique list of groups. * Add an isMember property to each group indicating whether the logged in user is a member. @@ -34,7 +36,7 @@ export function combineGroups( uri: string | null, settings: SidebarSettings, ) { - const worldGroup = featuredGroups.find(g => g.id === '__world__'); + const worldGroup = featuredGroups.find(g => g.id === PUBLIC_GROUP_ID); if (worldGroup) { userGroups.unshift(worldGroup); } @@ -50,7 +52,11 @@ export function combineGroups( // Set flag indicating whether user can leave group. for (const group of groups) { - group.canLeave = allowLeavingGroups(settings) && group.isMember; + group.canLeave = + allowLeavingGroups(settings) && + group.isMember && + // People should not be able to leave the "Public" group. + group.id !== PUBLIC_GROUP_ID; } // Add isScopedToUri property indicating whether a group is within scope diff --git a/src/sidebar/helpers/test/groups-test.js b/src/sidebar/helpers/test/groups-test.js index dafb8c58d35..445eab8ad89 100644 --- a/src/sidebar/helpers/test/groups-test.js +++ b/src/sidebar/helpers/test/groups-test.js @@ -97,6 +97,40 @@ describe('sidebar/helpers/groups', () => { }, ); + it('sets `canLeave` to false for the `__world__` group', () => { + const userGroups = [ + { id: '__world__', name: 'Public', type: 'open' }, + { id: 'groupa', name: 'GroupA', type: 'private' }, + { id: 'groupc', name: 'GroupC', type: 'open' }, + { id: 'groupd', name: 'GroupD', type: 'restricted' }, + ]; + const groups = combineGroups(userGroups, [], 'https://foo.com/bar'); + + const expected = [ + { + id: '__world__', + canLeave: false, + }, + { + id: 'groupa', + canLeave: true, + }, + { + id: 'groupc', + canLeave: true, + }, + { + id: 'groupd', + canLeave: true, + }, + ]; + + for (const { id, canLeave } of expected) { + const group = groups.find(g => g.id === id); + assert.strictEqual(group.canLeave, canLeave); + } + }); + it('combines groups from both lists uniquely', () => { const userGroups = [ { id: 'groupa', name: 'GroupA' }, diff --git a/src/sidebar/services/groups.ts b/src/sidebar/services/groups.ts index abb09f887d2..bedfb667b55 100644 --- a/src/sidebar/services/groups.ts +++ b/src/sidebar/services/groups.ts @@ -7,7 +7,7 @@ import type { SidebarSettings } from '../../types/config'; import type { Service } from '../../types/config'; import { serviceConfig } from '../config/service-config'; import { isReply } from '../helpers/annotation-metadata'; -import { combineGroups } from '../helpers/groups'; +import { combineGroups, PUBLIC_GROUP_ID } from '../helpers/groups'; import type { SidebarStore } from '../store'; import { awaitStateChange } from '../store/util'; import { watch } from '../util/watch'; @@ -121,7 +121,7 @@ export class GroupsService { // If the main document URL has no groups associated with it, always show // the "Public" group. const pageHasAssociatedGroups = groups.some( - g => g.id !== '__world__' && g.isScopedToUri, + g => g.id !== PUBLIC_GROUP_ID && g.isScopedToUri, ); if (!pageHasAssociatedGroups) { return groups; @@ -130,14 +130,14 @@ export class GroupsService { // If directLinkedGroup or directLinkedAnnotationGroupId is the "Public" group, // always return groups. if ( - directLinkedGroupId === '__world__' || - directLinkedAnnotationGroupId === '__world__' + directLinkedGroupId === PUBLIC_GROUP_ID || + directLinkedAnnotationGroupId === PUBLIC_GROUP_ID ) { return groups; } // Return non-world groups. - return groups.filter(g => g.id !== '__world__'); + return groups.filter(g => g.id !== PUBLIC_GROUP_ID); } /**