diff --git a/lib/permissions/minimally-encoded-thread-permissions.js b/lib/permissions/minimally-encoded-thread-permissions.js --- a/lib/permissions/minimally-encoded-thread-permissions.js +++ b/lib/permissions/minimally-encoded-thread-permissions.js @@ -9,6 +9,7 @@ ThreadPermissionsInfo, ThreadRolePermissionsBlob, } from '../types/thread-permission-types.js'; +import { threadPermissions } from '../types/thread-permission-types.js'; import { entries, invertObjectToMap } from '../utils/objects.js'; import type { TRegex } from '../utils/validation-utils.js'; import { tRegex } from '../utils/validation-utils.js'; @@ -111,13 +112,18 @@ return false; } const permissionBitmask = minimallyEncodedThreadPermissions[permission]; + const knowOfBitmask = + minimallyEncodedThreadPermissions[threadPermissions.KNOW_OF]; invariant( // TODO (atul): Update flow to `194.0.0` for bigint support // $FlowIssue illegal-typeof typeof permissionBitmask === 'bigint', 'permissionBitmask must be of type bigint', ); - return (permissionsBitmask & permissionBitmask) !== BigInt(0); + return ( + (permissionsBitmask & permissionBitmask) !== BigInt(0) && + (permissionsBitmask & knowOfBitmask) !== BigInt(0) + ); }; const propagationPrefixes = Object.freeze({ 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 @@ -74,6 +74,30 @@ }); }); +describe('hasPermission', () => { + const permissionsSansKnowOf = { + know_of: { value: false, source: null }, + visible: { value: true, source: '1' }, + }; + const permissionsSansKnowOfBitmask = permissionsToBitmaskHex( + permissionsSansKnowOf, + ); + it('should fail check if know_of is false even if permission specified in request is true', () => { + expect(hasPermission(permissionsSansKnowOfBitmask, 'visible')).toBe(false); + }); + + const permissionsWithKnowOf = { + know_of: { value: true, source: '1' }, + visible: { value: true, source: '1' }, + }; + const permissionsWithKnowOfBitmask = permissionsToBitmaskHex( + permissionsWithKnowOf, + ); + it('should succeed permission check if know_of is true', () => { + expect(hasPermission(permissionsWithKnowOfBitmask, 'visible')).toBe(true); + }); +}); + describe('threadPermissionsFromBitmaskHex', () => { const expectedDecodedThreadPermissions = { know_of: { value: true, source: 'null' },