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
Copy file name to clipboardExpand all lines: README.md
+53-9Lines changed: 53 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -126,16 +126,12 @@ Easy!
126
126
### Define Abilities
127
127
128
128
> [!NOTE]
129
-
> With the upcoming Nuxt4, you can store your abilities in the `app/utils/abilities.ts` file. Then, you can import them in your server folder using `~/utils/abilities`.
130
-
> See an example with [the project Orion](https://github.com/Barbapapazes/orion/blob/main/app/utils/users/abilities.ts).
131
-
132
-
> [!NOTE]
133
-
> With Nuxt4, a new `shared` directory will be introduced to easily share code between the client and the server.
134
-
> See [the issue](https://github.com/nuxt/nuxt/issues/28675).
129
+
> With Nuxt 4, a new `shared` directory will be introduced to easily share code between the client and the server.
130
+
> See [the video from Alexander Lichter](https://youtu.be/_m5ct5e8nVo?si=2iNcPVMttlIq5fLR).
135
131
136
132
Now the resolvers are set up, you can define your first ability. An ability is a function that takes at least the user, and returns a boolean to indicate if the user can perform the action. It can also take additional arguments.
137
133
138
-
I recommend to create a new file `utils/abilities.ts` to create your abilities:
134
+
I recommend to create a new file `shared/utils/abilities.ts` to create your abilities:
139
135
140
136
```ts
141
137
exportconst listPosts =defineAbility(() =>true) // Only authenticated users can list posts
If you have many abilities, you could prefer to create a directory `utils/abilities/` and create a file for each ability. Having the abilities in the `utils` directory allows auto-import to work in the client while having a simple import in the server `~/utils/abilities`.
144
+
If you have many abilities, you could prefer to create a directory `shared/utils/abilities/` and create a file for each ability. Having the abilities in the `shared/utils` directory allows auto-import to work in the client while having a simple import in the server `~~/shared/utils/abilities`. **Remember that the shared folder only exports the first level of the directory.** So you have to export the abilities in the `shared/utils/abilities/index.ts` file.
149
145
150
146
By default, guests are not allowed to perform any action and the ability is not called. This behavior can be changed per ability:
151
147
@@ -157,7 +153,7 @@ Now, unauthenticated users can list posts.
157
153
158
154
### Use Abilities
159
155
160
-
To use ability, you have access to 3 bouncer functions: `allows`, `denies`, and `authorize`. Both of them are available in the client and the server. _The implementation is different but the API is the same and it's entirely transparent the developer._
156
+
To use ability, you have access to 3 bouncer functions: `allows`, `denies`, and `authorize`. Both of them are available in the client and the server. _The implementation is different but the API is (nearly) the same and it's entirely transparent the developer. On the server, the first parameter is the `event` from the handler._
161
157
162
158
The `allows` function returns a boolean if the user can perform the action:
163
159
@@ -167,6 +163,14 @@ if (await allows(listPosts)) {
167
163
}
168
164
```
169
165
166
+
_For the server:_
167
+
168
+
```ts
169
+
if (awaitallows(event, listPosts)) {
170
+
// User can list posts
171
+
}
172
+
```
173
+
170
174
The `denies` function returns a boolean if the user cannot perform the action:
171
175
172
176
```ts
@@ -175,6 +179,14 @@ if (await denies(editPost, post)) {
175
179
}
176
180
```
177
181
182
+
_For the server:_
183
+
184
+
```ts
185
+
if (awaitdenies(event, editPost, post)) {
186
+
// User cannot edit the post
187
+
}
188
+
```
189
+
178
190
The `authorize` function throws an error if the user cannot perform the action:
You can customize the error message and the status code per return value of the ability. This can be useful to return a 404 instead of a 403 to keep the user unaware of the existence of the resource.
187
205
188
206
```ts
@@ -248,6 +266,32 @@ The `Bouncer` component offers a more flexible and centralized way to handle bot
248
266
</Bouncer>
249
267
```
250
268
269
+
All of these components accept a prop named `as` to define the HTML tag to render. By default, it's a renderless component.
0 commit comments