1 | # fastify-guard
|
2 | > A simple user role and scope checker plugin to protect endpoints for [Fastify](https://github.com/fastify/fastify).
|
3 |
|
4 | [![NPM](https://nodei.co/npm/fastify-guard.png)](https://nodei.co/npm/fastify-guard/)
|
5 |
|
6 | `fastify-guard` is designed to protect API endpoints by checking authenticated user roles and/or scopes if they met or not. `guard` is the registered Fastify decorator and can be used in anywhere.
|
7 |
|
8 | Inspired by [express-jwt-permissions](https://github.com/MichielDeMey/express-jwt-permissions).
|
9 |
|
10 | ## Options
|
11 |
|
12 | | Name | Type | Default | Description |
|
13 | | --- | --- | --- | --- |
|
14 | | requestProperty | string | `user` | The authenticated user property name that fastify-guard will search in request object |
|
15 | | roleProperty | string | `role` | The role property name that fastify-guard will search in authenticated user object |
|
16 | | scopeProperty | string | `scope` | The scope property name that fastify-guard will search in authenticated user object |
|
17 | | errorHandler | function | undefined | Custom error handler to manipulate the response that will be returned. As fallback, default HTTP error messages will be returned. |
|
18 |
|
19 | ## API
|
20 |
|
21 | ### `guard.role(role)`
|
22 |
|
23 | Returns a function which checks if the authenticated user has the given role(s). Multiple roles can be sent as separated parameters or in an array. If the given role(s) was not assigned to the authenticated user, the function will throw an HTTP Error (if no errorHandler provided in options otherwise the errorHandler will be invoked). The function supposed to be used in `preHandler` hook.
|
24 |
|
25 | ### `guard.hasRole(request, role)`
|
26 |
|
27 | Returns a boolean value which indicates the authenticated user has the given role.
|
28 |
|
29 | `request` is the Fastify request object
|
30 |
|
31 | `role` is role name
|
32 |
|
33 | ### `guard.scope(scope)`
|
34 |
|
35 | Returns a function which checks if the authenticated user has the given scope(s). Multiple scopes can be sent as separated parameters or in an array. If the given scope(s) was not assigned to the authenticated user, the function will throw an HTTP Error (if no errorHandler provided in options otherwise the errorHandler will be invoked). The function supposed to be used in `preHandler` hook.
|
36 |
|
37 | ### `guard.hasScope(request, scope)`
|
38 |
|
39 | Returns a boolean value which indicates the authenticated user has the given scope.
|
40 |
|
41 | `request` is the Fastify request object
|
42 |
|
43 | `scope` is scope name
|
44 |
|
45 | ## Examples
|
46 |
|
47 | ```js
|
48 | // get required modules
|
49 | const fastify = require('fastify')()
|
50 | const fastifyGuard = require('fastify-guard')
|
51 |
|
52 | // register fastify-guard plugin
|
53 | fastify.register(
|
54 | fastifyGuard,
|
55 | {
|
56 | errorHandler: (result, req, reply) => {
|
57 | return reply.send('you are not allowed to call this route')
|
58 | }
|
59 | }
|
60 | )
|
61 |
|
62 | // this route can only be called by users who has 'cto' and 'admin' roles
|
63 | fastify.get(
|
64 | '/admin',
|
65 | { preHandler: [fastify.guard.role(['cto', 'admin'])] },
|
66 | (req, reply) => {
|
67 | // 'user' should already be defined in req object
|
68 | reply.send(req.user)
|
69 | }
|
70 | )
|
71 |
|
72 | // this route can only be called by users who has 'admin' or 'editor' role
|
73 | fastify.get(
|
74 | '/',
|
75 | { preHandler: [fastify.guard.role('admin', 'editor')] },
|
76 | (req, reply) => {
|
77 | // 'user' should already be defined in req object
|
78 | reply.send(req.user)
|
79 | }
|
80 | )
|
81 |
|
82 | /*
|
83 | http://localhost:3000 -> will print out below result if the authenticated user does not have 'admin' role
|
84 |
|
85 | you are not allowed to call this route
|
86 | */
|
87 |
|
88 | fastify.get(
|
89 | '/has-role',
|
90 | (req, reply) => {
|
91 | // 'user' should already be defined in req object
|
92 | reply.send(
|
93 | fastify.guard.hasRole(req, 'admin') // will return a boolean value
|
94 | )
|
95 | }
|
96 | )
|
97 |
|
98 | fastify.get(
|
99 | '/has-scope',
|
100 | (req, reply) => {
|
101 | // 'user' should already be defined in req object
|
102 | reply.send(
|
103 | fastify.guard.hasScope(req, 'profile') // will return a boolean value
|
104 | )
|
105 | }
|
106 | )
|
107 |
|
108 | // initialize the fastify server
|
109 | fastify.listen(3000, () => {
|
110 | console.log('Fastify server is running on port: 3000')
|
111 | })
|
112 |
|
113 | /*
|
114 | http://localhost:3000 -> will print out below result if the authenticated user does not have 'admin' role
|
115 |
|
116 | you are not allowed to call this route
|
117 | */
|
118 | ```
|
119 |
|
120 | ## Installation
|
121 | `npm install fastify-guard`
|
122 |
|
123 | ## Contribution
|
124 | Contributions and pull requests are kindly welcomed!
|
125 |
|
126 | ## License
|
127 | This project is licensed under the terms of the [MIT license](https://github.com/hsynlms/fastify-guard/blob/master/LICENSE).
|