diff --git a/lib/permissions/minimally-encoded-raw-thread-info-validators.js b/lib/permissions/minimally-encoded-raw-thread-info-validators.js --- a/lib/permissions/minimally-encoded-raw-thread-info-validators.js +++ b/lib/permissions/minimally-encoded-raw-thread-info-validators.js @@ -8,7 +8,7 @@ } from './minimally-encoded-thread-permissions.js'; import { specialRoleValidator } from './special-roles.js'; import type { - MemberInfo, + MemberInfoWithPermissions, ThreadCurrentUserInfo, RawThreadInfo, RoleInfo, @@ -62,17 +62,18 @@ isDefault: t.maybe(t.Boolean), }); -const memberInfoValidator: TInterface = tShape({ - ...legacyMemberInfoValidator.meta.props, - minimallyEncoded: tBool(true), - permissions: tHexEncodedPermissionsBitmask, -}); +const memberInfoWithPermissionsValidator: TInterface = + tShape({ + ...legacyMemberInfoValidator.meta.props, + minimallyEncoded: tBool(true), + permissions: tHexEncodedPermissionsBitmask, + }); const rawThreadInfoValidator: TInterface = tShape( { ...legacyRawThreadInfoValidator.meta.props, minimallyEncoded: tBool(true), - members: t.list(memberInfoValidator), + members: t.list(memberInfoWithPermissionsValidator), roles: t.dict(tID, roleInfoValidator), currentUser: threadCurrentUserInfoValidator, }, @@ -99,7 +100,7 @@ ]); export { - memberInfoValidator, + memberInfoWithPermissionsValidator, roleInfoValidator, persistedRoleInfoValidator, threadCurrentUserInfoValidator, diff --git a/lib/permissions/minimally-encoded-thread-permissions.test.js b/lib/permissions/minimally-encoded-thread-permissions.test.js --- a/lib/permissions/minimally-encoded-thread-permissions.test.js +++ b/lib/permissions/minimally-encoded-thread-permissions.test.js @@ -1,7 +1,7 @@ // @flow import { - memberInfoValidator, + memberInfoWithPermissionsValidator, persistedRoleInfoValidator, rawThreadInfoValidator, roleInfoValidator, @@ -471,7 +471,7 @@ describe('minimallyEncodedMemberInfoValidator', () => { it('should validate correctly formed MinimallyEncodedMemberInfo', () => { expect( - memberInfoValidator.is({ + memberInfoWithPermissionsValidator.is({ minimallyEncoded: true, id: 'memberID', permissions: 'ABCDEF', @@ -480,7 +480,7 @@ ).toBe(true); expect( - memberInfoValidator.is({ + memberInfoWithPermissionsValidator.is({ minimallyEncoded: true, id: 'memberID', permissions: '01b', @@ -491,7 +491,7 @@ it('should NOT validate malformed MinimallyEncodedMemberInfo', () => { expect( - memberInfoValidator.is({ + memberInfoWithPermissionsValidator.is({ minimallyEncoded: true, id: 'memberID', permissions: 'INVALID', @@ -500,7 +500,7 @@ ).toBe(false); expect( - memberInfoValidator.is({ + memberInfoWithPermissionsValidator.is({ minimallyEncoded: true, id: 'memberID', permissions: 100, diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js --- a/lib/shared/thread-utils.js +++ b/lib/shared/thread-utils.js @@ -42,7 +42,7 @@ import type { RelativeMemberInfo, RawThreadInfo, - MemberInfo, + MemberInfoWithPermissions, RoleInfo, ThreadInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; @@ -139,7 +139,7 @@ return _mapValues((threadInfo: ThreadInfo) => { const keyedMembers = _keyBy('id')(threadInfo.members); const keyedMembersToRole = _mapValues( - (member: MemberInfo | RelativeMemberInfo) => { + (member: MemberInfoWithPermissions | RelativeMemberInfo) => { return member.role ? threadInfo.roles[member.role] : null; }, )(keyedMembers); @@ -304,7 +304,7 @@ } function threadActualMembers( - memberInfos: $ReadOnlyArray, + memberInfos: $ReadOnlyArray, ): $ReadOnlyArray { return memberInfos .filter(memberInfo => memberInfo.role) @@ -312,7 +312,7 @@ } function threadOtherMembers< - T: LegacyMemberInfo | MemberInfo | RelativeMemberInfo, + T: LegacyMemberInfo | MemberInfoWithPermissions | RelativeMemberInfo, >(memberInfos: $ReadOnlyArray, viewerID: ?string): $ReadOnlyArray { return memberInfos.filter( memberInfo => memberInfo.role && memberInfo.id !== viewerID, @@ -1002,7 +1002,7 @@ // Since we don't have access to all of the ancestor ThreadInfos, we approximate // "parent admin" as anybody with CHANGE_ROLE permissions. function memberHasAdminPowers( - memberInfo: LegacyMemberInfo | MemberInfo | ServerMemberInfo, + memberInfo: LegacyMemberInfo | MemberInfoWithPermissions | ServerMemberInfo, ): boolean { if (memberInfo.minimallyEncoded) { return hasPermission(memberInfo.permissions, threadPermissions.CHANGE_ROLE); diff --git a/lib/types/minimally-encoded-thread-permissions-types.js b/lib/types/minimally-encoded-thread-permissions-types.js --- a/lib/types/minimally-encoded-thread-permissions-types.js +++ b/lib/types/minimally-encoded-thread-permissions-types.js @@ -99,7 +99,7 @@ }; }; -export type MemberInfo = $ReadOnly<{ +export type MemberInfoWithPermissions = $ReadOnly<{ ...LegacyMemberInfo, +minimallyEncoded: true, +permissions: string, @@ -107,7 +107,7 @@ const minimallyEncodeMemberInfo = ( memberInfo: LegacyMemberInfo, -): MemberInfo => { +): MemberInfoWithPermissions => { invariant( !('minimallyEncoded' in memberInfo), 'memberInfo is already minimally encoded.', @@ -120,7 +120,7 @@ }; const decodeMinimallyEncodedMemberInfo = ( - minimallyEncodedMemberInfo: MemberInfo, + minimallyEncodedMemberInfo: MemberInfoWithPermissions, ): LegacyMemberInfo => { const { minimallyEncoded, ...rest } = minimallyEncodedMemberInfo; return { @@ -143,7 +143,7 @@ export type RawThreadInfo = $ReadOnly<{ ...LegacyRawThreadInfo, +minimallyEncoded: true, - +members: $ReadOnlyArray, + +members: $ReadOnlyArray, +roles: { +[id: string]: RoleInfo }, +currentUser: ThreadCurrentUserInfo, }>; diff --git a/lib/utils/thread-ops-utils.js b/lib/utils/thread-ops-utils.js --- a/lib/utils/thread-ops-utils.js +++ b/lib/utils/thread-ops-utils.js @@ -3,12 +3,12 @@ import invariant from 'invariant'; import { - memberInfoValidator, + memberInfoWithPermissionsValidator, persistedRoleInfoValidator, threadCurrentUserInfoValidator, } from '../permissions/minimally-encoded-raw-thread-info-validators.js'; import type { - MemberInfo, + MemberInfoWithPermissions, RawThreadInfo, RoleInfo, } from '../types/minimally-encoded-thread-permissions-types.js'; @@ -46,18 +46,17 @@ ): RawThreadInfo { // 1. Validate and potentially minimally encode `rawMembers`. const rawMembers = JSON.parse(clientDBThreadInfo.members); - const minimallyEncodedMembers: $ReadOnlyArray = rawMembers.map( - rawMember => { + const minimallyEncodedMembers: $ReadOnlyArray = + rawMembers.map(rawMember => { invariant( - memberInfoValidator.is(rawMember) || + memberInfoWithPermissionsValidator.is(rawMember) || legacyMemberInfoValidator.is(rawMember), 'rawMember must be valid [MinimallyEncoded/Legacy]MemberInfo', ); return rawMember.minimallyEncoded ? rawMember : minimallyEncodeMemberInfo(rawMember); - }, - ); + }); // 2. Validate and potentially minimally encode `rawRoles`. const rawRoles = JSON.parse(clientDBThreadInfo.roles);