@superawesome/permissions
Version:
Fine grained permissions / access control with ownerships & attribute picking, done right.
89 lines (70 loc) • 4.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PermissionDefinitionInternal = exports.PermissionDefinitionDefaults = void 0;
/**
__NOTE: This class `PermissionDefinition_DOCS` is a dummy one, it is only the placeholder for docs for the real [PermissionDefinition](/miscellaneous/typealiases.html#PermissionDefinition) which is a type alias__.
A `PermissionDefinition` (in short **PD**) is the fundamental way to define **permission rules**:
> It grants which **Actions** (eg `approve`, `follow`) a **Role** (eg `EMPLOYEE`) can perform on a **Resource** (eg `Document`), whether on **any** Resource or only on **own** ones.
The grants can also restrict some *Role-Action-Resource* declarations to:
- touch only specific **attributes**, defined as an array of attributes names (eg `['title', 'price']`) & optionally glob notation (eg `'*'` or `'!confidentialNotes'`).
- perform an action only on **OWN Resources**, where Ownership is defined as **ownership** hooks (i.e async callbacks) that define how the give roles own an particular resource.
__Note__ : when you use **any ownership hook**, the following rules apply:
- you 'll need to implement `isOwner` for sure.
- also need to implement one of `listOwned` OR `limitOwned`, but not both.
i.e its an all or nothing, also enforced as runtime check - see the reasoning in the [FAQ](/additional-documentation/faq,-gotchas-&-caveats.html).
__Note__: A PermissionDefinition is a loose definition, meaning that all of the props are **optional**. This is because users can use [defaults](/classes/PermissionDefinitionDefaults.html), use [shortcut syntax for grant actions](/classes/PermissionDefinition_DOCS.html#grant) etc.
At runtime though, your complete PDs are validated thoroughly at the earliest possible - see [Principles](/additional-documentation/philosophy,-principles-&-architecture.html).
## Example
```typescript
{
roles: ['EMPLOYEE', 'REGISTERED_USER'],
resource: 'document',
descr: "I can CRUD only OWN Documents (i.e created by me)." +
"I can read all but 'confidential' fields.",
isOwner: async ({ user, resourceId }) => await isUserOwnerOfDocument({ user, resourceId }),
listOwned: async user => await listOfUserOwnedDocumentIds(user),
grant: {
'create:own': ['*'],
'read:own': ['*', '!confidential'],
'update:own': ['*', '!confidential'],
'delete:own': ['*'],
},
}
```
*/
// eslint-disable-next-line @typescript-eslint/class-name-casing
class PermissionDefinition_DOCS {
}
/**
* @internal
* This is an internal class - see [PermissionDefinition_DOCS](/classes/PermissionDefinition_DOCS.html)
*/
class PermissionDefinitionNoOwnershipInternal {
}
/**
* @internal
* This is an internal class - see [PermissionDefinition_DOCS](/classes/PermissionDefinition_DOCS.html)
*/
class PermissionDefinitionWithOwnershipInternal extends PermissionDefinitionNoOwnershipInternal {
}
/**
The optional `PermissionDefinitionDefaults` is a single object (a Partial of [`PermissionDefinition`](/classes/PermissionDefinition_DOCS.html)) whose property values are merged with each [`PermissionDefinition`](/classes/PermissionDefinition_DOCS.html) instance, if an instance's property value is missing.
For example, in the code below:
```typescript
const pdDefaults: PermissionDefinitionDefaults = { resource: 'document' };
permissions.addDefinitions([ {PD1}, {PD2}, ..., {PDn} ], pdDefaults);
```
all PDs that are missing the `resource` property, they will end up with the `{ resource: 'document' }`.
*/
class PermissionDefinitionDefaults {
}
exports.PermissionDefinitionDefaults = PermissionDefinitionDefaults;
/**
@internal
All `PermissionDefinition` are converted internally to a set of `PermissionDefinitionInternal`, after some consolidation takes place to settle defaults, remove duplicates etc.
A `PermissionDefinitionInternal` is **strict** and **self complete**, i.e it has settled/inherited the defaults and thus nas no missing props.
*/
class PermissionDefinitionInternal {
}
exports.PermissionDefinitionInternal = PermissionDefinitionInternal;
//# sourceMappingURL=PermissionDefinitions.js.map