You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[mongoose] is a popular JavaScript ODM for [MongoDB]. `@casl/mongoose` provides 2 plugins that allow to integrate `@casl/ability` and mongoose in few minutes:
21
+
`@casl/mongoose` can be integrated not only with [mongoose] but also with any [MongoDB] JS driver thanks to new `accessibleBy` helper function.
22
+
23
+
### `accessibleBy` helper
24
+
25
+
This neat helper function allows to convert ability rules to MongoDB query and fetch only accessible records from the database. It can be used with mongoose or [MongoDB adapter][mongo-adapter]:
This can also be combined with other conditions with help of `$and` operator:
50
+
51
+
```js
52
+
posts =awaitdb.collection('posts').find({
53
+
$and: [
54
+
accessibleBy(ability, 'update').Post,
55
+
{ public:true }
56
+
]
57
+
});
58
+
```
59
+
60
+
**Important!**: never use spread operator (i.e., `...`) to combine conditions provided by `accessibleBy` with something else because you may accidentally overwrite properties that restrict access to particular records:
In the case above, we overwrote `authorId` property and basically allowed non-authorized access to posts of author with `id = 2`
73
+
74
+
If there are no permissions defined for particular action/subjectType, `accessibleBy` will return `{ $expr: false }` and when it's sent to MongoDB, it will return an empty result set.
`accessibleBy` returns a `Proxy` instance and then we access particular subject type by reading its property. Property name is then passed to `Ability` methods as `subjectType`. With Typescript we can restrict this properties only to know record types:
89
+
90
+
#### `accessibleBy` in TypeScript
91
+
92
+
If we want to get hints in IDE regarding what record types (i.e., entity or model names) can be accessed in return value of `accessibleBy` we can easily do this by using module augmentation:
accessibleBy(ability).User// allows only User and Post properties
106
+
```
107
+
108
+
This can be done either centrally, in the single place or it can be defined in every model/entity definition file. For example, we can augment `@casl/mongoose` in every mongoose model definition file:
Historically, `@casl/mongoose` was intended for super easy integration with [mongoose] but now we re-orient it to be more MongoDB specific package because mongoose keeps bringing complexity and issues with ts types.
22
128
23
129
### Accessible Records plugin
24
130
131
+
This plugin is deprecated, the recommended way is to use [`accessibleBy` helper function](#accessibleBy-helper)
132
+
25
133
`accessibleRecordsPlugin` is a plugin which adds `accessibleBy` method to query and static methods of mongoose models. We can add this plugin globally:
As you can see, a static method returns all fields that can be read for all posts. At the same time, an instance method returns fields that can be read from this particular `post` instance. That's why there is no much sense (except you want to reduce traffic between app and database) to pass the result of static method into `mongoose.Query`'s `select` method because eventually you will need to call `accessibleFieldsBy` on every instance.
203
311
204
-
## Integration with other MongoDB libraries
205
-
206
-
In case you don't use mongoose, this package provides `toMongoQuery` function which can convert CASL rules into [MongoDB] query. Lets see an example of how to fetch accessible records using raw [MongoDB adapter][mongo-adapter]
// returns null if ability does not allow to update posts
221
-
posts = [];
222
-
} else {
223
-
posts =awaitdb.collection('posts').find(query);
224
-
}
225
-
} finally {
226
-
db.close();
227
-
}
228
-
229
-
console.log(posts);
230
-
}
231
-
```
232
-
233
-
## TypeScript support
312
+
## TypeScript support in mongoose
234
313
235
314
The package is written in TypeScript, this makes it easier to work with plugins and `toMongoQuery` helper because IDE provides useful hints. Let's see it in action!
0 commit comments