Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
bitmask-flags
Advanced tools
A utility for working with bitmasks to do flags and permissions. Supports flag inheritance.
While the examples in this documentation will show usage for a permission system, you could of course use it for any kind of flags.
WTFPL or CC0, whichever you prefer.
Maintaining open-source projects takes a lot of time, and the more donations I receive, the more time I can dedicate to open-source. If this module is useful to you, consider making a donation!
You can donate using Bitcoin, PayPal, Flattr, cash-in-mail, SEPA transfers, and pretty much anything else. Thank you!
Pull requests welcome. Please make sure your modifications are in line with the overall code style, and ensure that you're editing the .coffee
files, not the .js
files.
As this module could potentially deal with authentication, tests are needed; a pull request for those would be especially welcome.
Build tool of choice is gulp
; simply run gulp
while developing, and it will watch for changes.
Be aware that by making a pull request, you agree to release your modifications under the licenses stated above.
var bitmaskFlags = require("bitmask-flags");
var flagHandler = bitmaskFlags({
view_announcements: 1,
create_announcements: {
value: 2,
inheritedFlags: ["edit_announcements"]
},
edit_announcements: 4,
delete_announcements: 8
});
Why you need to explicitly specify the values for each flag? Because if they were assigned automatically in order, it'd be too easy to accidentally mess up the values of your flags during later editing or rearranging. Especially in a permission system, that could have disastrous consequences.
bitmask-flags
will do a sanity check on instantiating to ensure that all of your flags are a power of 2. If that's not the case, it will throw an Error and bail out.
The user
object is a hypothetical ORM model/object of some sort. It hypothetically supports plain attributes and has a save() method, for the sake of illustrating how this module works.
var permissions = flagHandler.create(); // This is how you create a new value, starting at 0 (no flags).
// or
var permissions = flagHandler.create(user.permissions); // This is how you use an existing starting value (eg. from the database).
// or
var permissions = flagHandler.create(user.permissions, user.originalPermissions); // If you want to use flag inheritance (explained later).
permissions.add("view_announcements"); // This permission is now set.
permissions.add("delete_announcements"); // The value now has `view_announcements` and `delete_announcements` flags.
permissions.remove("view_announcements"); // Now only `delete_announcements` is left.
console.log(permissions.has("delete_announcements")); // true
user.permissions = permissions.getValue();
user.save(); // Done!
The really interesting thing, though, is flag inheritance. Sometimes one flag should automatically grant another flag, but the other flag can also be granted separately. bitmask-flags
makes this easy.
Note that you will have to store two values in your database for this to work, rather than one - the second value indicates which flags were explicitly set. This way, when you've explicitly set a child flag, unsetting the parent flag won't change the state of the child flag. That also means you can explicitly set a flag that was already set through inheritance, and have it persist.
For these examples, we will assume that the section above never happened, and the user starts out with no permissions.
var permissions = flagHandler.create(user.permissions, user.originalPermissions); // Like we saw before...
permissions.add("create_announcements"); // The user now has `create_announcements` AND `edit_anouncements`.
console.log(permissions.has("edit_announcements")); // true
permissions.remove("create_announcements"); // The user now has no permissions.
console.log(permissions.has("edit_announcements")); // false
/* Now let's try that again, but this time explicitly setting `edit_announcements`. */
permissions.add("create_announcements"); // The user now has `create_announcements` and `edit_anouncements`.
permissions.add("edit_announcements"); // The user *still* has `create_announcements` and `edit_anouncements`.
permissions.remove("create_announcements");
console.log(permissions.has("edit_announcements")); // true - Because we set `edit_announcements` explicitly, it wasn't unset along with `create_announcements`. Magic!
user.permissions = permissions.getValue();
user.originalPermissions = permissions.getOriginalValue();
user.save(); // Done! The inheritance structure will persist, even through database loads and saves.
In this example, getValue()
will return the effective value (ie. all flags that are set), while getOriginalValue()
will only return a value consisting of the explicitly set flags. This second value is what is used to keep track of inherited permissions, and should be passed as a second argument to .create
when creating a new value.
Returns a new bitmaskFlags instance with the given flagMap
. The flagMap
is an object that maps flag names to values and, optionally, inheritances.
Each value in the flagMap
object can either be an object with options, or a number directly. All values should be powers of two. See the Example section for a usage example.
An Error is thrown if there is a problem with the flagMap; eg. one of the values is not a power of two, or one of the inheritances refers to a non-existent flag.
The rest of the API documentation will refer to the returned value as flagHandler
.
Creates a new value.
The rest of the API documentation will refer to the returned value as flagValue
.
Replaces the current flagMap
of the handler with a new one. The same sanity checks are performed as for bitmaskFlags(flagMap)
, and the same input is accepted.
Returns the current flagMap
.
Returns an array of flags that inherited from the specified flag.
Returns the internal bitmask value for the specified flag. This is the value originally specified in the flagMap
.
You almost certainly won't need this; look at the flagValue
API methods instead.
Sets the flag (if it is not yet set). Also sets any inherited flags.
Unsets the flag (if it is set). Also unsets any inherited flags, except for those that were explicitly set (assuming an initialOriginalValue was specified).
Returns whether the specified flag is set or not.
Returns the current value as a Number. This is what you'll want to use for storing the effective value in a database.
It is the value that you will pass to flagHandler.create([initialValue, [initialOriginalValue]])
as the first argument (initialValue
).
Returns the current 'original value' as a Number. This represents the explicitly set flags, and you will have to store this in your database as a separate value for full inheritance support.
It is the value that you will pass to flagHandler.create([initialValue, [initialOriginalValue]])
as the second argument (initialOriginalValue
).
Returns an array of all the flags (names, not values) that are set in the current value, both explicit and inherited.
You probably won't need this, unless you're trying to debug something.
1.0.0 (August 17, 2016)
First stable release - however, the functionality or API has not changed from 0.0.2
.
FAQs
A utility for dealing with flags and permissions using bitmasks.
The npm package bitmask-flags receives a total of 271 weekly downloads. As such, bitmask-flags popularity was classified as not popular.
We found that bitmask-flags demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.