export enum Permission { NONE = 0, ADMIN = 2, MANAGE_USERS = 8, MANAGE_REQUESTS = 16, REQUEST = 32, VOTE = 64, AUTO_APPROVE = 128, AUTO_APPROVE_MOVIE = 256, AUTO_APPROVE_TV = 512, REQUEST_4K = 1024, REQUEST_4K_MOVIE = 2048, REQUEST_4K_TV = 4096, REQUEST_ADVANCED = 8192, REQUEST_VIEW = 16384, AUTO_APPROVE_4K = 32768, AUTO_APPROVE_4K_MOVIE = 65536, AUTO_APPROVE_4K_TV = 131072, REQUEST_MOVIE = 262144, REQUEST_TV = 524288, MANAGE_ISSUES = 1048576, VIEW_ISSUES = 2097152, CREATE_ISSUES = 4194304, RECENT_VIEW = 67108864, } export interface PermissionCheckOptions { type: 'and' | 'or'; } /** * Takes a Permission and the users permission value and determines * if the user has access to the permission provided. If the user has * the admin permission, true will always be returned from this check! * * @param permissions Single permission or array of permissions * @param value users current permission value * @param options Extra options to control permission check behavior (mainly for arrays) */ export const hasPermission = ( permissions: Permission | Permission[], value: number, options: PermissionCheckOptions = { type: 'and' } ): boolean => { let total = 0; // If we are not checking any permissions, bail out and return true if (permissions === 0) { return true; } if (Array.isArray(permissions)) { if (value & Permission.ADMIN) { return true; } switch (options.type) { case 'and': return permissions.every((permission) => !!(value & permission)); case 'or': return permissions.some((permission) => !!(value & permission)); } } else { total = permissions; } return !!(value & Permission.ADMIN) || !!(value & total); };