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 @@ -127,10 +127,39 @@ return bitmask.toString(16); }; +// TODO (atul): Update flow to `194.0.0` for bigint support +// $FlowIssue bigint-unsupported +const inversePermissionVariantBit: Map = new Map( + Object.entries(permissionVariantBit).map(([key, value]) => [value, key]), +); + +const bitmaskHexToRolePermissions = ( + bitmaskHex: string, +): ThreadRolePermissionsBlob => { + const bitmask = BigInt(`0x${bitmaskHex}`); + const threadRolePermissions = {}; + + Object.keys(minimallyEncodedThreadPermissions).forEach((permission, idx) => { + // Extract 12-bit segment for this permission + const shiftAmount = BigInt(idx) * BigInt(12); + // `& BigInt('0xfff')` masks all but lowest 12 bits + const permissionBitmask = (bitmask >> shiftAmount) & BigInt('0xfff'); + + inversePermissionVariantBit.forEach((value, key) => { + if ((permissionBitmask & key) === key) { + threadRolePermissions[`${value}${permission}`] = true; + } + }); + }); + + return threadRolePermissions; +}; + export { minimallyEncodedThreadPermissions, permissionsToBitmaskHex, hasPermission, rolePermissionToBitmask, rolePermissionsToBitmaskHex, + bitmaskHexToRolePermissions, }; 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,6 +1,7 @@ // @flow import { + bitmaskHexToRolePermissions, hasPermission, permissionsToBitmaskHex, rolePermissionsToBitmaskHex, @@ -230,5 +231,19 @@ expect(bitmaskB).toBe( '1001001001000001001001b24001001000001001001001001c7dc7d', ); + + expect( + bitmaskHexToRolePermissions( + '1001001001000001001001b24001001000001001001001001c7dc7d', + ), + ).toStrictEqual(permissionsB); + + expect( + rolePermissionsToBitmaskHex( + bitmaskHexToRolePermissions( + '1001001001000001001001b24001001000001001001001001c7dc7d', + ), + ), + ).toStrictEqual('1001001001000001001001b24001001000001001001001001c7dc7d'); }); });