diff --git a/lib/permissions/thread-permissions.js b/lib/permissions/thread-permissions.js --- a/lib/permissions/thread-permissions.js +++ b/lib/permissions/thread-permissions.js @@ -348,8 +348,10 @@ function getRolePermissionBlobs(threadType: ThreadType): RolePermissionBlobs { if (threadTypeIsThick(threadType)) { const thickThreadType = assertThickThreadType(threadType); - const memberPermissions = - getThickThreadRolePermissionsBlob(thickThreadType); + const memberPermissions = getThickThreadRolePermissionsBlob( + thickThreadType, + true, + ); return { Members: memberPermissions, }; @@ -464,8 +466,20 @@ function getThickThreadRolePermissionsBlob( threadType: ThickThreadType, + isMember: boolean, ): ThreadRolePermissionsBlob { invariant(threadTypeIsThick(threadType), 'ThreadType should be thick'); + + if (!isMember && threadType === threadTypes.THICK_SIDEBAR) { + return { + [threadPermissions.KNOW_OF]: true, + [threadPermissions.VISIBLE]: true, + [threadPermissions.JOIN_THREAD]: true, + }; + } else if (!isMember) { + return {}; + } + const basePermissions = { [threadPermissions.KNOW_OF]: true, [threadPermissions.VISIBLE]: true, diff --git a/lib/shared/dm-ops/create-thread-spec.js b/lib/shared/dm-ops/create-thread-spec.js --- a/lib/shared/dm-ops/create-thread-spec.js +++ b/lib/shared/dm-ops/create-thread-spec.js @@ -36,7 +36,7 @@ threadID: string, roleID: string, ): { +role: RoleInfo, +membershipPermissions: ThreadPermissionsInfo } { - const rolePermissions = getThickThreadRolePermissionsBlob(threadType); + const rolePermissions = getThickThreadRolePermissionsBlob(threadType, true); const membershipPermissions = getAllThreadPermissions( makePermissionsBlob(rolePermissions, null, threadID, threadType), threadID, @@ -86,6 +86,23 @@ const { membershipPermissions, role } = createRoleAndPermissionForThickThreads(threadType, threadID, roleID); + const isViewerMember = allMemberIDsWithSubscriptions.some( + member => member.id === viewerID, + ); + let viewerMembershipPermissions = membershipPermissions; + let viewerRoleID: ?string = role.id; + if (!isViewerMember) { + const rolePermissions = getThickThreadRolePermissionsBlob( + threadType, + false, + ); + viewerMembershipPermissions = getAllThreadPermissions( + makePermissionsBlob(rolePermissions, null, threadID, threadType), + threadID, + ); + viewerRoleID = null; + } + const newThread: MutableThickRawThreadInfo = { thick: true, minimallyEncoded: true, @@ -98,8 +115,11 @@ ({ id: memberID, subscription }) => minimallyEncodeMemberInfo({ id: memberID, - role: role.id, - permissions: membershipPermissions, + role: memberID === viewerID ? viewerRoleID : role.id, + permissions: + memberID === viewerID + ? viewerMembershipPermissions + : membershipPermissions, isSender: memberID === viewerID, subscription, }), @@ -108,8 +128,8 @@ [role.id]: role, }, currentUser: minimallyEncodeThreadCurrentUserInfo({ - role: role.id, - permissions: membershipPermissions, + role: viewerRoleID, + permissions: viewerMembershipPermissions, subscription: joinThreadSubscription, unread, }), diff --git a/lib/shared/dm-ops/leave-thread-spec.js b/lib/shared/dm-ops/leave-thread-spec.js --- a/lib/shared/dm-ops/leave-thread-spec.js +++ b/lib/shared/dm-ops/leave-thread-spec.js @@ -7,6 +7,12 @@ DMOperationSpec, ProcessDMOperationUtilities, } from './dm-op-spec.js'; +import { permissionsToBitmaskHex } from '../../permissions/minimally-encoded-thread-permissions.js'; +import { + getAllThreadPermissions, + getThickThreadRolePermissionsBlob, + makePermissionsBlob, +} from '../../permissions/thread-permissions.js'; import type { DMLeaveThreadOperation } from '../../types/dm-ops.js'; import { messageTypes } from '../../types/message-types-enum.js'; import type { ThickRawThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; @@ -115,9 +121,30 @@ ...memberTimestamps[editorID], isMember: time, }; + + let currentUser = threadInfo.currentUser; + if (editorID === viewerID) { + const rolePermissions = getThickThreadRolePermissionsBlob( + threadInfo.type, + false, + ); + const viewerMembershipPermissions = permissionsToBitmaskHex( + getAllThreadPermissions( + makePermissionsBlob(rolePermissions, null, threadID, threadInfo.type), + threadID, + ), + ); + currentUser = { + ...currentUser, + role: null, + permissions: viewerMembershipPermissions, + }; + } + const updatedThreadInfo = { ...threadInfo, members: threadInfo.members.filter(member => member.id !== editorID), + currentUser, timestamps: { ...threadInfo.timestamps, members: memberTimestamps,