Page MenuHomePhabricator

D13418.id44541.diff
No OneTemporary

D13418.id44541.diff

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
@@ -466,6 +466,10 @@
threadType: ThickThreadType,
): ThreadRolePermissionsBlob {
invariant(threadTypeIsThick(threadType), 'ThreadType should be thick');
+ const openDescendantKnowOf = OPEN_DESCENDANT + threadPermissions.KNOW_OF;
+ const openDescendantVisible = OPEN_DESCENDANT + threadPermissions.VISIBLE;
+ const openChildJoinThread = OPEN_CHILD + threadPermissions.JOIN_THREAD;
+
const basePermissions = {
[threadPermissions.KNOW_OF]: true,
[threadPermissions.VISIBLE]: true,
@@ -493,6 +497,9 @@
...basePermissions,
[threadPermissions.EDIT_ENTRIES]: true,
[threadPermissions.CREATE_SIDEBARS]: true,
+ [openDescendantKnowOf]: true,
+ [openDescendantVisible]: true,
+ [openChildJoinThread]: true,
};
}
return {
@@ -501,6 +508,9 @@
[threadPermissions.CREATE_SIDEBARS]: true,
[threadPermissions.ADD_MEMBERS]: true,
[threadPermissions.LEAVE_THREAD]: true,
+ [openDescendantKnowOf]: true,
+ [openDescendantVisible]: true,
+ [openChildJoinThread]: true,
};
}
diff --git a/lib/shared/dm-ops/add-members-spec.js b/lib/shared/dm-ops/add-members-spec.js
--- a/lib/shared/dm-ops/add-members-spec.js
+++ b/lib/shared/dm-ops/add-members-spec.js
@@ -70,10 +70,27 @@
roleIsDefaultRole(role),
)?.id;
invariant(defaultRoleID, 'Default role ID must exist');
+
+ const parentThreadID = currentThreadInfo.parentThreadID;
+ const parentThreadInfo = parentThreadID
+ ? utilities.threadInfos[parentThreadID]
+ : null;
+ if (parentThreadID && !parentThreadInfo) {
+ console.log(
+ `Parent thread with ID ${parentThreadID} was expected while adding ` +
+ 'thread members but is missing from the store',
+ );
+ }
+ invariant(
+ !parentThreadInfo || parentThreadInfo.thick,
+ 'Parent thread should be thick',
+ );
+
const { membershipPermissions } = createRoleAndPermissionForThickThreads(
currentThreadInfo.type,
currentThreadInfo.id,
defaultRoleID,
+ parentThreadInfo,
);
const memberTimestamps = { ...currentThreadInfo.timestamps.members };
diff --git a/lib/shared/dm-ops/add-viewer-to-thread-members-spec.js b/lib/shared/dm-ops/add-viewer-to-thread-members-spec.js
--- a/lib/shared/dm-ops/add-viewer-to-thread-members-spec.js
+++ b/lib/shared/dm-ops/add-viewer-to-thread-members-spec.js
@@ -55,7 +55,7 @@
) => {
const { time, messageID, addedUserIDs, existingThreadDetails } =
dmOperation;
- const { viewerID, threadInfos } = utilities;
+ const { threadInfos } = utilities;
const { rawMessageInfo } =
createAddViewerToThreadMembersMessageDataWithInfoFromDMOp(dmOperation);
@@ -115,7 +115,7 @@
},
},
},
- viewerID,
+ utilities,
);
const updateInfos = [
{
diff --git a/lib/shared/dm-ops/create-sidebar-spec.js b/lib/shared/dm-ops/create-sidebar-spec.js
--- a/lib/shared/dm-ops/create-sidebar-spec.js
+++ b/lib/shared/dm-ops/create-sidebar-spec.js
@@ -153,7 +153,7 @@
containingThreadID: parentThreadID,
timestamps: createThreadTimestamps(time, allMemberIDs),
},
- viewerID,
+ utilities,
);
const { sidebarSourceMessageInfo, createSidebarMessageInfo } =
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
@@ -1,5 +1,6 @@
// @flow
+import invariant from 'invariant';
import uuid from 'uuid';
import type {
@@ -11,6 +12,7 @@
getAllThreadPermissions,
makePermissionsBlob,
getThickThreadRolePermissionsBlob,
+ makePermissionsForChildrenBlob,
} from '../../permissions/thread-permissions.js';
import type {
CreateThickRawThreadInfoInput,
@@ -34,16 +36,58 @@
import { rawMessageInfoFromMessageData } from '../message-utils.js';
import { createThreadTimestamps } from '../thread-utils.js';
+function createPermissionsInfo(
+ threadID: string,
+ threadType: ThickThreadType,
+ isMember: boolean,
+ parentThreadInfo: ?ThickRawThreadInfo,
+): ThreadPermissionsInfo {
+ let rolePermissions = null;
+ if (isMember) {
+ rolePermissions = getThickThreadRolePermissionsBlob(threadType);
+ }
+
+ let permissionsFromParent = null;
+ if (parentThreadInfo) {
+ const parentThreadRolePermissions = getThickThreadRolePermissionsBlob(
+ parentThreadInfo.type,
+ );
+ const parentPermissionsBlob = makePermissionsBlob(
+ parentThreadRolePermissions,
+ null,
+ parentThreadInfo.id,
+ parentThreadInfo.type,
+ );
+ permissionsFromParent = makePermissionsForChildrenBlob(
+ parentPermissionsBlob,
+ );
+ }
+
+ return getAllThreadPermissions(
+ makePermissionsBlob(
+ rolePermissions,
+ permissionsFromParent,
+ threadID,
+ threadType,
+ ),
+ threadID,
+ );
+}
+
function createRoleAndPermissionForThickThreads(
threadType: ThickThreadType,
threadID: string,
roleID: string,
+ parentThreadInfo: ?ThickRawThreadInfo,
): { +role: RoleInfo, +membershipPermissions: ThreadPermissionsInfo } {
const rolePermissions = getThickThreadRolePermissionsBlob(threadType);
- const membershipPermissions = getAllThreadPermissions(
- makePermissionsBlob(rolePermissions, null, threadID, threadType),
+ const membershipPermissions = createPermissionsInfo(
threadID,
+ threadType,
+ true,
+ parentThreadInfo,
);
+
const role: RoleInfo = {
...minimallyEncodeRoleInfo({
id: roleID,
@@ -62,7 +106,7 @@
type MutableThickRawThreadInfo = { ...ThickRawThreadInfo };
function createThickRawThreadInfo(
input: CreateThickRawThreadInfoInput,
- viewerID: string,
+ utilities: ProcessDMOperationUtilities,
): MutableThickRawThreadInfo {
const {
threadID,
@@ -86,8 +130,38 @@
const memberIDs = allMemberIDsWithSubscriptions.map(({ id }) => id);
const threadColor = color ?? generatePendingThreadColor(memberIDs);
+ const parentThreadInfo = parentThreadID
+ ? utilities.threadInfos[parentThreadID]
+ : null;
+ if (parentThreadID && !parentThreadInfo) {
+ console.log(
+ `Parent thread with ID ${parentThreadID} was expected while creating ` +
+ 'thick thread but is missing from the store',
+ );
+ }
+ invariant(
+ !parentThreadInfo || parentThreadInfo.thick,
+ 'Parent thread should be thick',
+ );
+
const { membershipPermissions, role } =
- createRoleAndPermissionForThickThreads(threadType, threadID, roleID);
+ createRoleAndPermissionForThickThreads(
+ threadType,
+ threadID,
+ roleID,
+ parentThreadInfo,
+ );
+
+ const viewerIsMember = allMemberIDsWithSubscriptions.some(
+ member => member.id === utilities.viewerID,
+ );
+ const viewerRoleID = viewerIsMember ? role.id : null;
+ const viewerMembershipPermissions = createPermissionsInfo(
+ threadID,
+ threadType,
+ viewerIsMember,
+ parentThreadInfo,
+ );
const newThread: MutableThickRawThreadInfo = {
thick: true,
@@ -101,9 +175,12 @@
({ id: memberID, subscription }) =>
minimallyEncodeMemberInfo<ThickMemberInfo>({
id: memberID,
- role: role.id,
- permissions: membershipPermissions,
- isSender: memberID === viewerID,
+ role: memberID === utilities.viewerID ? viewerRoleID : role.id,
+ permissions:
+ memberID === utilities.viewerID
+ ? viewerMembershipPermissions
+ : membershipPermissions,
+ isSender: memberID === utilities.viewerID,
subscription,
}),
),
@@ -111,8 +188,8 @@
[role.id]: role,
},
currentUser: minimallyEncodeThreadCurrentUserInfo({
- role: role.id,
- permissions: membershipPermissions,
+ role: viewerRoleID,
+ permissions: viewerMembershipPermissions,
subscription: joinThreadSubscription,
unread,
}),
@@ -189,7 +266,7 @@
unread: creatorID !== viewerID,
timestamps: createThreadTimestamps(time, allMemberIDs),
},
- viewerID,
+ utilities,
);
const { rawMessageInfo } =
@@ -222,4 +299,5 @@
createThickRawThreadInfo,
createThreadSpec,
createRoleAndPermissionForThickThreads,
+ createPermissionsInfo,
};
diff --git a/lib/shared/dm-ops/join-thread-spec.js b/lib/shared/dm-ops/join-thread-spec.js
--- a/lib/shared/dm-ops/join-thread-spec.js
+++ b/lib/shared/dm-ops/join-thread-spec.js
@@ -118,7 +118,7 @@
members: memberTimestamps,
},
},
- viewerID,
+ utilities,
);
updateInfos.push({
type: updateTypes.JOIN_THREAD,
@@ -135,10 +135,27 @@
roleIsDefaultRole(role),
)?.id;
invariant(defaultRoleID, 'Default role ID must exist');
+
+ const parentThreadID = existingThreadDetails.parentThreadID;
+ const parentThreadInfo = parentThreadID
+ ? utilities.threadInfos[parentThreadID]
+ : null;
+ if (parentThreadID && !parentThreadInfo) {
+ console.log(
+ `Parent thread with ID ${parentThreadID} was expected while joining ` +
+ 'thick thread but is missing from the store',
+ );
+ }
+ invariant(
+ !parentThreadInfo || parentThreadInfo.thick,
+ 'Parent thread should be thick',
+ );
+
const { membershipPermissions } = createRoleAndPermissionForThickThreads(
currentThreadInfo.type,
currentThreadInfo.id,
defaultRoleID,
+ parentThreadInfo,
);
const member = minimallyEncodeMemberInfo<ThickMemberInfo>({
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
@@ -3,6 +3,7 @@
import invariant from 'invariant';
import uuid from 'uuid';
+import { createPermissionsInfo } from './create-thread-spec.js';
import type {
DMOperationSpec,
ProcessDMOperationUtilities,
@@ -10,6 +11,7 @@
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';
+import { minimallyEncodeThreadCurrentUserInfo } from '../../types/minimally-encoded-thread-permissions-types.js';
import { threadTypes } from '../../types/thread-types-enum.js';
import type { RawThreadInfos } from '../../types/thread-types.js';
import { updateTypes } from '../../types/update-types-enum.js';
@@ -121,9 +123,41 @@
...memberTimestamps[editorID],
isMember: time,
};
+
+ let currentUser = threadInfo.currentUser;
+ if (editorID === viewerID) {
+ const parentThreadID = threadInfo.parentThreadID;
+ const parentThreadInfo = parentThreadID
+ ? utilities.threadInfos[parentThreadID]
+ : null;
+ if (parentThreadID && !parentThreadInfo) {
+ console.log(
+ `Parent thread with ID ${parentThreadID} was expected while ` +
+ 'leaving a thread but is missing from the store',
+ );
+ }
+ invariant(
+ parentThreadInfo?.thick,
+ 'Parent thread should be present and thick',
+ );
+ const viewerMembershipPermissions = createPermissionsInfo(
+ threadID,
+ threadInfo.type,
+ false,
+ parentThreadInfo,
+ );
+ const { minimallyEncoded, permissions, ...currentUserInfo } = currentUser;
+ currentUser = minimallyEncodeThreadCurrentUserInfo({
+ ...currentUserInfo,
+ role: null,
+ permissions: viewerMembershipPermissions,
+ });
+ }
+
const updatedThreadInfo = {
...threadInfo,
members: threadInfo.members.filter(member => member.id !== editorID),
+ currentUser,
timestamps: {
...threadInfo.timestamps,
members: memberTimestamps,

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 20, 5:35 AM (20 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2329320
Default Alt Text
D13418.id44541.diff (11 KB)

Event Timeline