Basic Permissions Class

A simple class to manage permissions

Basic permissions example with bitwise

Usage example at the bottom of the codeblock

export class Permission {
  private permissions: bigint;

  private static readonly PERMISSIONS = {
    NONE: 0n,
    READ: 1n << 0n,
    WRITE: 1n << 1n,
    ADMIN: 1n << 2n,
    OWNER: 1n << 3n,
    // Add more permissions here (make sure to increase the last number by one)
  } as const;

  constructor(permission: bigint = 0n) {
    this.permissions = permission;
  }

  getPermissions(): { string: string; array: PermissionKey[] } {
    const userPermissions = Object.entries(Permission.PERMISSIONS)
      .filter(([, value]) => (this.permissions & value) !== 0n)
      .map(([key]) => key as PermissionKey);

    return { string: this.permissions.toString(), array: userPermissions };
  }

  setPermissions(
    permissionArray: PermissionKey[]
  ): ReturnType<Permission["getPermissions"]> {
    this.permissions = permissionArray.reduce(
      (acc, key) => acc | Permission.PERMISSIONS[key],
      0n
    );
    return this.getPermissions();
  }

  removePermissions(
    permissionArray: PermissionKey[]
  ): ReturnType<Permission["getPermissions"]> {
    this.permissions &= ~permissionArray.reduce(
      (acc, key) => acc | Permission.PERMISSIONS[key],
      0n
    );
    return this.getPermissions();
  }

  addPermissions(
    permissionArray: PermissionKey[]
  ): ReturnType<Permission["getPermissions"]> {
    this.permissions |= permissionArray.reduce(
      (acc, key) => acc | Permission.PERMISSIONS[key],
      0n
    );
    return this.getPermissions();
  }

  hasAnyPermission(permissionArray: PermissionKey[]): boolean {
    const requiredPermissions = permissionArray.reduce(
      (acc, key) => acc | Permission.PERMISSIONS[key],
      0n
    );
    return (this.permissions & requiredPermissions) !== 0n;
  }

  hasAllPermissions(permissionArray: PermissionKey[]): boolean {
    const requiredPermissions = permissionArray.reduce(
      (acc, key) => acc | Permission.PERMISSIONS[key],
      0n
    );
    return (this.permissions & requiredPermissions) === requiredPermissions;
  }

  static getPermissionKeys(): PermissionKey[] {
    return Object.keys(Permission.PERMISSIONS) as PermissionKey[];
  }
}

export type PermissionKey = keyof (typeof Permission)["PERMISSIONS"];

// Usage example
const permission = new Permission();

permission.setPermissions(["ADMIN", "OWNER"]);
console.log(permission.getPermissions()); // { string: "12", array: ['ADMIN', 'OWNER'] }

permission.addPermissions(["READ"]);
console.log(permission.getPermissions()); // { string: "13", array: ['READ', 'ADMIN', 'OWNER'] }

permission.removePermissions(["ADMIN"]);
console.log(permission.getPermissions()); // { string: "9", array: ['READ', 'OWNER'] }

console.log(permission.hasAnyPermission(["READ", "WRITE", "ADMIN"])); // true
console.log(permission.hasAllPermissions(["READ", "OWNER"])); // true
console.log(permission.hasAllPermissions(["READ", "ADMIN"])); // false

console.log(Permission.getPermissionKeys()); // ['NONE', 'READ', 'WRITE', 'ADMIN', 'OWNER']