wabe 0.6.9 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -32
- package/bucket/b.txt +1 -0
- package/dev/index.ts +215 -0
- package/dist/authentication/Session.d.ts +4 -1
- package/dist/authentication/interface.d.ts +16 -0
- package/dist/email/interface.d.ts +1 -1
- package/dist/graphql/resolvers.d.ts +4 -2
- package/dist/hooks/index.d.ts +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +8713 -8867
- package/dist/server/index.d.ts +4 -2
- package/dist/utils/crypto.d.ts +7 -0
- package/dist/utils/helper.d.ts +4 -1
- package/generated/schema.graphql +16 -14
- package/generated/wabe.ts +4 -4
- package/package.json +15 -15
- package/src/authentication/OTP.test.ts +69 -0
- package/src/authentication/OTP.ts +66 -0
- package/src/authentication/Session.test.ts +665 -0
- package/src/authentication/Session.ts +529 -0
- package/src/authentication/defaultAuthentication.ts +214 -0
- package/src/authentication/index.ts +3 -0
- package/src/authentication/interface.ts +157 -0
- package/src/authentication/oauth/GitHub.test.ts +105 -0
- package/src/authentication/oauth/GitHub.ts +133 -0
- package/src/authentication/oauth/Google.test.ts +105 -0
- package/src/authentication/oauth/Google.ts +110 -0
- package/src/authentication/oauth/Oauth2Client.test.ts +225 -0
- package/src/authentication/oauth/Oauth2Client.ts +140 -0
- package/src/authentication/oauth/index.ts +2 -0
- package/src/authentication/oauth/utils.test.ts +35 -0
- package/src/authentication/oauth/utils.ts +28 -0
- package/src/authentication/providers/EmailOTP.test.ts +138 -0
- package/src/authentication/providers/EmailOTP.ts +93 -0
- package/src/authentication/providers/EmailPassword.test.ts +187 -0
- package/src/authentication/providers/EmailPassword.ts +130 -0
- package/src/authentication/providers/EmailPasswordSRP.test.ts +206 -0
- package/src/authentication/providers/EmailPasswordSRP.ts +184 -0
- package/src/authentication/providers/GitHub.ts +30 -0
- package/src/authentication/providers/Google.ts +30 -0
- package/src/authentication/providers/OAuth.test.ts +185 -0
- package/src/authentication/providers/OAuth.ts +112 -0
- package/src/authentication/providers/PhonePassword.test.ts +187 -0
- package/src/authentication/providers/PhonePassword.ts +129 -0
- package/src/authentication/providers/QRCodeOTP.test.ts +79 -0
- package/src/authentication/providers/QRCodeOTP.ts +65 -0
- package/src/authentication/providers/index.ts +6 -0
- package/src/authentication/resolvers/refreshResolver.test.ts +37 -0
- package/src/authentication/resolvers/refreshResolver.ts +20 -0
- package/src/authentication/resolvers/signInWithResolver.inte.test.ts +59 -0
- package/src/authentication/resolvers/signInWithResolver.test.ts +307 -0
- package/src/authentication/resolvers/signInWithResolver.ts +102 -0
- package/src/authentication/resolvers/signOutResolver.test.ts +41 -0
- package/src/authentication/resolvers/signOutResolver.ts +22 -0
- package/src/authentication/resolvers/signUpWithResolver.test.ts +186 -0
- package/src/authentication/resolvers/signUpWithResolver.ts +69 -0
- package/src/authentication/resolvers/verifyChallenge.test.ts +136 -0
- package/src/authentication/resolvers/verifyChallenge.ts +69 -0
- package/src/authentication/roles.test.ts +59 -0
- package/src/authentication/roles.ts +40 -0
- package/src/authentication/utils.test.ts +99 -0
- package/src/authentication/utils.ts +43 -0
- package/src/cache/InMemoryCache.test.ts +62 -0
- package/src/cache/InMemoryCache.ts +45 -0
- package/src/cron/index.test.ts +17 -0
- package/src/cron/index.ts +46 -0
- package/src/database/DatabaseController.test.ts +625 -0
- package/src/database/DatabaseController.ts +983 -0
- package/src/database/index.test.ts +1230 -0
- package/src/database/index.ts +9 -0
- package/src/database/interface.ts +312 -0
- package/src/email/DevAdapter.ts +8 -0
- package/src/email/EmailController.test.ts +29 -0
- package/src/email/EmailController.ts +13 -0
- package/src/email/index.ts +2 -0
- package/src/email/interface.ts +36 -0
- package/src/email/templates/sendOtpCode.ts +120 -0
- package/src/file/FileController.ts +28 -0
- package/src/file/FileDevAdapter.ts +54 -0
- package/src/file/hookDeleteFile.ts +27 -0
- package/src/file/hookReadFile.ts +70 -0
- package/src/file/hookUploadFile.ts +53 -0
- package/src/file/index.test.ts +979 -0
- package/src/file/index.ts +2 -0
- package/src/file/interface.ts +42 -0
- package/src/graphql/GraphQLSchema.test.ts +4399 -0
- package/src/graphql/GraphQLSchema.ts +928 -0
- package/src/graphql/index.ts +2 -0
- package/src/graphql/parseGraphqlSchema.ts +94 -0
- package/src/graphql/parser.test.ts +217 -0
- package/src/graphql/parser.ts +566 -0
- package/src/graphql/pointerAndRelationFunction.ts +200 -0
- package/src/graphql/resolvers.ts +467 -0
- package/src/graphql/tests/aggregation.test.ts +1123 -0
- package/src/graphql/tests/e2e.test.ts +596 -0
- package/src/graphql/tests/scalars.test.ts +250 -0
- package/src/graphql/types.ts +219 -0
- package/src/hooks/HookObject.test.ts +122 -0
- package/src/hooks/HookObject.ts +168 -0
- package/src/hooks/authentication.ts +76 -0
- package/src/hooks/createUser.test.ts +77 -0
- package/src/hooks/createUser.ts +10 -0
- package/src/hooks/defaultFields.test.ts +187 -0
- package/src/hooks/defaultFields.ts +40 -0
- package/src/hooks/deleteSession.test.ts +181 -0
- package/src/hooks/deleteSession.ts +20 -0
- package/src/hooks/hashFieldHook.test.ts +163 -0
- package/src/hooks/hashFieldHook.ts +97 -0
- package/src/hooks/index.test.ts +207 -0
- package/src/hooks/index.ts +430 -0
- package/src/hooks/permissions.test.ts +424 -0
- package/src/hooks/permissions.ts +113 -0
- package/src/hooks/protected.test.ts +551 -0
- package/src/hooks/protected.ts +72 -0
- package/src/hooks/searchableFields.test.ts +166 -0
- package/src/hooks/searchableFields.ts +98 -0
- package/src/hooks/session.test.ts +138 -0
- package/src/hooks/session.ts +78 -0
- package/src/hooks/setEmail.test.ts +216 -0
- package/src/hooks/setEmail.ts +35 -0
- package/src/hooks/setupAcl.test.ts +589 -0
- package/src/hooks/setupAcl.ts +29 -0
- package/src/index.ts +9 -0
- package/src/schema/Schema.test.ts +484 -0
- package/src/schema/Schema.ts +795 -0
- package/src/schema/defaultResolvers.ts +94 -0
- package/src/schema/index.ts +1 -0
- package/src/schema/resolvers/meResolver.test.ts +62 -0
- package/src/schema/resolvers/meResolver.ts +14 -0
- package/src/schema/resolvers/newFile.ts +0 -0
- package/src/schema/resolvers/resetPassword.test.ts +345 -0
- package/src/schema/resolvers/resetPassword.ts +64 -0
- package/src/schema/resolvers/sendEmail.test.ts +118 -0
- package/src/schema/resolvers/sendEmail.ts +21 -0
- package/src/schema/resolvers/sendOtpCode.test.ts +153 -0
- package/src/schema/resolvers/sendOtpCode.ts +52 -0
- package/src/security.test.ts +3461 -0
- package/src/server/defaultSessionHandler.test.ts +66 -0
- package/src/server/defaultSessionHandler.ts +115 -0
- package/src/server/generateCodegen.ts +476 -0
- package/src/server/index.test.ts +552 -0
- package/src/server/index.ts +354 -0
- package/src/server/interface.ts +11 -0
- package/src/server/routes/authHandler.ts +187 -0
- package/src/server/routes/index.ts +40 -0
- package/src/utils/crypto.test.ts +41 -0
- package/src/utils/crypto.ts +121 -0
- package/src/utils/export.ts +13 -0
- package/src/utils/helper.ts +195 -0
- package/src/utils/index.test.ts +11 -0
- package/src/utils/index.ts +201 -0
- package/src/utils/preload.ts +8 -0
- package/src/utils/testHelper.ts +117 -0
- package/tsconfig.json +32 -0
- package/bunfig.toml +0 -4
- package/dist/ai/index.d.ts +0 -1
- package/dist/ai/interface.d.ts +0 -9
- /package/dist/server/{defaultHandlers.d.ts → defaultSessionHandler.d.ts} +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DevWabeTypes } from '../utils/helper'
|
|
2
|
+
import type { HookObject } from './HookObject'
|
|
3
|
+
|
|
4
|
+
const updateEmail = (object: HookObject<DevWabeTypes, 'User'>) => {
|
|
5
|
+
const authentication = object.getNewData().authentication
|
|
6
|
+
|
|
7
|
+
if (!authentication) return
|
|
8
|
+
|
|
9
|
+
// Considering that we only have one authentication provider (for double auth maybe need an adjustment)
|
|
10
|
+
const provider = Object.keys(authentication)[0] || ''
|
|
11
|
+
|
|
12
|
+
const emailToSave = authentication[provider].email
|
|
13
|
+
|
|
14
|
+
if (!emailToSave) return
|
|
15
|
+
|
|
16
|
+
object.upsertNewData('email', emailToSave)
|
|
17
|
+
|
|
18
|
+
if (provider) object.upsertNewData('provider', provider)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// This hook works for official authentication provider that store email in "email" field
|
|
22
|
+
// Maybe need custom hook for custom authentication provider
|
|
23
|
+
export const defaultSetEmail = (object: HookObject<DevWabeTypes, 'User'>) => {
|
|
24
|
+
if (object.isFieldUpdated('email')) return
|
|
25
|
+
|
|
26
|
+
updateEmail(object)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const defaultSetEmailOnUpdate = (
|
|
30
|
+
object: HookObject<DevWabeTypes, 'User'>,
|
|
31
|
+
) => {
|
|
32
|
+
if (object.isFieldUpdated('email')) return
|
|
33
|
+
|
|
34
|
+
updateEmail(object)
|
|
35
|
+
}
|
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
beforeAll,
|
|
4
|
+
afterAll,
|
|
5
|
+
it,
|
|
6
|
+
expect,
|
|
7
|
+
afterEach,
|
|
8
|
+
mock,
|
|
9
|
+
} from 'bun:test'
|
|
10
|
+
import { gql, type GraphQLClient } from 'graphql-request'
|
|
11
|
+
import {
|
|
12
|
+
getAnonymousClient,
|
|
13
|
+
getGraphqlClient,
|
|
14
|
+
getUserClient,
|
|
15
|
+
type DevWabeTypes,
|
|
16
|
+
} from '../utils/helper'
|
|
17
|
+
import { setupTests, closeTests } from '../utils/testHelper'
|
|
18
|
+
import type { Wabe } from '../server'
|
|
19
|
+
|
|
20
|
+
const createUserAndUpdateRole = async ({
|
|
21
|
+
anonymousClient,
|
|
22
|
+
rootClient,
|
|
23
|
+
roleName,
|
|
24
|
+
port,
|
|
25
|
+
}: {
|
|
26
|
+
port: number
|
|
27
|
+
anonymousClient: GraphQLClient
|
|
28
|
+
rootClient: GraphQLClient
|
|
29
|
+
roleName: string
|
|
30
|
+
}) => {
|
|
31
|
+
const res = await anonymousClient.request<any>(graphql.signUpWith, {
|
|
32
|
+
input: {
|
|
33
|
+
authentication: {
|
|
34
|
+
emailPassword: {
|
|
35
|
+
email: 'email@test.fr',
|
|
36
|
+
password: 'password',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const resOfRoles = await rootClient.request<any>(gql`
|
|
43
|
+
query getRoles {
|
|
44
|
+
roles(where: {name: {equalTo: "${roleName}"}}) {
|
|
45
|
+
edges {
|
|
46
|
+
node {
|
|
47
|
+
id
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`)
|
|
53
|
+
|
|
54
|
+
const roleId = resOfRoles.roles.edges[0].node.id
|
|
55
|
+
|
|
56
|
+
await rootClient.request<any>(gql`
|
|
57
|
+
mutation updateUser {
|
|
58
|
+
updateUser(input: {id: "${res.signUpWith.id}", fields: {role: {link: "${roleId}"}}}) {
|
|
59
|
+
user {
|
|
60
|
+
id
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`)
|
|
65
|
+
|
|
66
|
+
const userClient = getUserClient(port, {
|
|
67
|
+
accessToken: res.signUpWith.accessToken,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
userClient,
|
|
72
|
+
roleId,
|
|
73
|
+
userId: res.signUpWith.id,
|
|
74
|
+
accessToken: res.signUpWith.accessToken,
|
|
75
|
+
refreshToken: res.signUpWith.refreshToken,
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const getRoleNameFromId = async (roleId: string, rootClient: GraphQLClient) => {
|
|
80
|
+
const resOfRoles = await rootClient.request<any>(gql`
|
|
81
|
+
query getRoles {
|
|
82
|
+
roles(where: {id: {equalTo: "${roleId}"}}) {
|
|
83
|
+
edges {
|
|
84
|
+
node {
|
|
85
|
+
name
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
`)
|
|
91
|
+
|
|
92
|
+
return resOfRoles.roles.edges[0].node.name
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
describe('setupAcl', () => {
|
|
96
|
+
let wabe: Wabe<DevWabeTypes>
|
|
97
|
+
let port: number
|
|
98
|
+
let anonymousClient: GraphQLClient
|
|
99
|
+
let rootClient: GraphQLClient
|
|
100
|
+
|
|
101
|
+
const mockCallback = mock(() => {})
|
|
102
|
+
|
|
103
|
+
beforeAll(async () => {
|
|
104
|
+
const setup = await setupTests([
|
|
105
|
+
{
|
|
106
|
+
name: 'SetupACL',
|
|
107
|
+
fields: {
|
|
108
|
+
test: {
|
|
109
|
+
type: 'String',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
permissions: {
|
|
113
|
+
create: {
|
|
114
|
+
requireAuthentication: false,
|
|
115
|
+
},
|
|
116
|
+
acl: async (hookObject) => {
|
|
117
|
+
await hookObject.addACL('users', {
|
|
118
|
+
userId: hookObject.context.user?.id || '',
|
|
119
|
+
read: true,
|
|
120
|
+
write: true,
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
await hookObject.addACL('roles', {
|
|
124
|
+
// @ts-expect-error
|
|
125
|
+
role: 'Client',
|
|
126
|
+
read: true,
|
|
127
|
+
write: true,
|
|
128
|
+
})
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'SetupACL2',
|
|
134
|
+
fields: {
|
|
135
|
+
test: {
|
|
136
|
+
type: 'String',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
permissions: {
|
|
140
|
+
create: {
|
|
141
|
+
requireAuthentication: false,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'SetupACL3',
|
|
147
|
+
fields: {
|
|
148
|
+
test: {
|
|
149
|
+
type: 'String',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
permissions: {
|
|
153
|
+
create: {
|
|
154
|
+
requireAuthentication: false,
|
|
155
|
+
},
|
|
156
|
+
acl: async (hookObject) => {
|
|
157
|
+
await hookObject.addACL('users', null)
|
|
158
|
+
await hookObject.addACL('roles', null)
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: 'SetupACL4',
|
|
164
|
+
fields: {
|
|
165
|
+
test: {
|
|
166
|
+
type: 'String',
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
permissions: {
|
|
170
|
+
create: {
|
|
171
|
+
requireAuthentication: false,
|
|
172
|
+
},
|
|
173
|
+
acl: mockCallback,
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'SetupACL5',
|
|
178
|
+
fields: {
|
|
179
|
+
test: {
|
|
180
|
+
type: 'String',
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
permissions: {
|
|
184
|
+
create: {
|
|
185
|
+
requireAuthentication: false,
|
|
186
|
+
},
|
|
187
|
+
acl: async (hookObject) => {
|
|
188
|
+
await hookObject.addACL('users', null)
|
|
189
|
+
|
|
190
|
+
await hookObject.addACL('roles', {
|
|
191
|
+
// @ts-expect-error
|
|
192
|
+
role: 'Client',
|
|
193
|
+
read: true,
|
|
194
|
+
write: false,
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
await hookObject.addACL('roles', {
|
|
198
|
+
// @ts-expect-error
|
|
199
|
+
role: 'Client2',
|
|
200
|
+
read: false,
|
|
201
|
+
write: true,
|
|
202
|
+
})
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: 'SetupACL6',
|
|
208
|
+
fields: {
|
|
209
|
+
test: {
|
|
210
|
+
type: 'String',
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
permissions: {
|
|
214
|
+
create: {
|
|
215
|
+
requireAuthentication: false,
|
|
216
|
+
},
|
|
217
|
+
acl: async (hookObject) => {
|
|
218
|
+
await hookObject.addACL('users', {
|
|
219
|
+
userId: hookObject.context.user?.id || '',
|
|
220
|
+
read: true,
|
|
221
|
+
write: true,
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
await hookObject.addACL('roles', {
|
|
225
|
+
// @ts-expect-error
|
|
226
|
+
role: 'Client',
|
|
227
|
+
read: true,
|
|
228
|
+
write: true,
|
|
229
|
+
})
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: 'SetupACL7',
|
|
235
|
+
fields: {
|
|
236
|
+
test: {
|
|
237
|
+
type: 'String',
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
permissions: {
|
|
241
|
+
create: {
|
|
242
|
+
requireAuthentication: false,
|
|
243
|
+
},
|
|
244
|
+
acl: async (hookObject) => {
|
|
245
|
+
await hookObject.addACL('users', {
|
|
246
|
+
userId: hookObject.context.user?.id || '',
|
|
247
|
+
read: true,
|
|
248
|
+
write: true,
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
await hookObject.addACL('roles', {
|
|
252
|
+
// @ts-expect-error
|
|
253
|
+
role: 'Client',
|
|
254
|
+
read: true,
|
|
255
|
+
write: true,
|
|
256
|
+
})
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: 'SetupACL8',
|
|
262
|
+
fields: {
|
|
263
|
+
test: {
|
|
264
|
+
type: 'String',
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
permissions: {
|
|
268
|
+
create: {
|
|
269
|
+
requireAuthentication: false,
|
|
270
|
+
},
|
|
271
|
+
read: {
|
|
272
|
+
requireAuthentication: false,
|
|
273
|
+
},
|
|
274
|
+
acl: async (hookObject) => {
|
|
275
|
+
await hookObject.addACL('users', {
|
|
276
|
+
userId: hookObject.context.user?.id || '',
|
|
277
|
+
read: true,
|
|
278
|
+
write: true,
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
await hookObject.addACL('roles', {
|
|
282
|
+
// @ts-expect-error
|
|
283
|
+
role: 'Client',
|
|
284
|
+
read: true,
|
|
285
|
+
write: true,
|
|
286
|
+
})
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
])
|
|
291
|
+
|
|
292
|
+
wabe = setup.wabe
|
|
293
|
+
|
|
294
|
+
port = setup.port
|
|
295
|
+
anonymousClient = getAnonymousClient(port)
|
|
296
|
+
rootClient = getGraphqlClient(port)
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
afterAll(async () => {
|
|
300
|
+
await closeTests(wabe)
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
afterEach(async () => {
|
|
304
|
+
await rootClient.request<any>(graphql.deleteUsers)
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
it('should not access to an object created with anonymous client when only user that create the object can access to it with ACL', async () => {
|
|
308
|
+
await anonymousClient.request<any>(gql`
|
|
309
|
+
mutation createUser {
|
|
310
|
+
createUser(input:{fields:{name: "test" }}){
|
|
311
|
+
user{
|
|
312
|
+
id
|
|
313
|
+
acl {
|
|
314
|
+
users {
|
|
315
|
+
userId
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
`)
|
|
322
|
+
|
|
323
|
+
const res = await rootClient.request<any>(gql`
|
|
324
|
+
query users {
|
|
325
|
+
users (where: {name: {equalTo: "test"}}) {
|
|
326
|
+
edges {
|
|
327
|
+
node {
|
|
328
|
+
id
|
|
329
|
+
acl {
|
|
330
|
+
users {
|
|
331
|
+
userId
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
`)
|
|
339
|
+
|
|
340
|
+
expect(res.users.edges[0].node.acl).not.toBeNull()
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
it('should add acl object with to owner (with role client2) is authenticated (on read)', async () => {
|
|
344
|
+
const { userClient, userId } = await createUserAndUpdateRole({
|
|
345
|
+
anonymousClient,
|
|
346
|
+
port,
|
|
347
|
+
roleName: 'Client2',
|
|
348
|
+
rootClient,
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
const res = await userClient.request<any>(gql`
|
|
352
|
+
mutation createSetupACL8 {
|
|
353
|
+
createSetupACL8(input: {fields: {test: "test"}}) {
|
|
354
|
+
setupACL8 {
|
|
355
|
+
id
|
|
356
|
+
acl {
|
|
357
|
+
users {
|
|
358
|
+
userId
|
|
359
|
+
read
|
|
360
|
+
write
|
|
361
|
+
}
|
|
362
|
+
roles {
|
|
363
|
+
roleId
|
|
364
|
+
read
|
|
365
|
+
write
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
`)
|
|
372
|
+
|
|
373
|
+
// User
|
|
374
|
+
expect(res.createSetupACL8.setupACL8.acl.users[0].userId).toEqual(userId)
|
|
375
|
+
expect(res.createSetupACL8.setupACL8.acl.users[0].read).toEqual(true)
|
|
376
|
+
expect(res.createSetupACL8.setupACL8.acl.users[0].write).toEqual(true)
|
|
377
|
+
|
|
378
|
+
// Role
|
|
379
|
+
expect(
|
|
380
|
+
await getRoleNameFromId(
|
|
381
|
+
res.createSetupACL8.setupACL8.acl.roles[0].roleId,
|
|
382
|
+
rootClient,
|
|
383
|
+
),
|
|
384
|
+
).toEqual('Client')
|
|
385
|
+
expect(res.createSetupACL8.setupACL8.acl.roles[0].read).toEqual(true)
|
|
386
|
+
expect(res.createSetupACL8.setupACL8.acl.roles[0].write).toEqual(true)
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
it('should not update acl object if the acl function is not present in permissions in the class', async () => {
|
|
390
|
+
const res = await rootClient.request<any>(gql`
|
|
391
|
+
mutation createSetupACL2 {
|
|
392
|
+
createSetupACL2(input: {fields: {test: "test"}}) {
|
|
393
|
+
setupACL2 {
|
|
394
|
+
id
|
|
395
|
+
acl {
|
|
396
|
+
users {
|
|
397
|
+
userId
|
|
398
|
+
read
|
|
399
|
+
write
|
|
400
|
+
}
|
|
401
|
+
roles {
|
|
402
|
+
roleId
|
|
403
|
+
read
|
|
404
|
+
write
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
`)
|
|
411
|
+
|
|
412
|
+
expect(res.createSetupACL2.setupACL2.acl).toBeNull()
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
it('should set read and write to false if the null value is provided for users and roles', async () => {
|
|
416
|
+
await rootClient.request<any>(gql`
|
|
417
|
+
mutation createSetupACL3 {
|
|
418
|
+
createSetupACL3(input: {fields: {test: "test"}}) {
|
|
419
|
+
setupACL3 {
|
|
420
|
+
id
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
`)
|
|
425
|
+
|
|
426
|
+
const res = await rootClient.request<any>(gql`
|
|
427
|
+
query setupACL3s {
|
|
428
|
+
setupACL3s {
|
|
429
|
+
edges {
|
|
430
|
+
node {
|
|
431
|
+
id
|
|
432
|
+
acl {
|
|
433
|
+
users {
|
|
434
|
+
userId
|
|
435
|
+
read
|
|
436
|
+
write
|
|
437
|
+
}
|
|
438
|
+
roles {
|
|
439
|
+
roleId
|
|
440
|
+
read
|
|
441
|
+
write
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
`)
|
|
449
|
+
|
|
450
|
+
// User
|
|
451
|
+
expect(res.setupACL3s.edges[0].node.acl.users).toHaveLength(0)
|
|
452
|
+
|
|
453
|
+
// Role
|
|
454
|
+
expect(res.setupACL3s.edges[0].node.acl.roles).toHaveLength(0)
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
it('should call acl function if provided', async () => {
|
|
458
|
+
await rootClient.request<any>(gql`
|
|
459
|
+
mutation createSetupACL4 {
|
|
460
|
+
createSetupACL4(input: {fields: {test: "test"}}) {
|
|
461
|
+
setupACL4 {
|
|
462
|
+
id
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
`)
|
|
467
|
+
|
|
468
|
+
expect(mockCallback).toHaveBeenCalledTimes(1)
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
it('should get different role id for read and write if roles are different', async () => {
|
|
472
|
+
const res = await rootClient.request<any>(gql`
|
|
473
|
+
mutation createSetupACL5 {
|
|
474
|
+
createSetupACL5(input: {fields: {test: "test"}}) {
|
|
475
|
+
setupACL5 {
|
|
476
|
+
id
|
|
477
|
+
acl {
|
|
478
|
+
users {
|
|
479
|
+
userId
|
|
480
|
+
read
|
|
481
|
+
write
|
|
482
|
+
}
|
|
483
|
+
roles {
|
|
484
|
+
roleId
|
|
485
|
+
read
|
|
486
|
+
write
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
`)
|
|
493
|
+
|
|
494
|
+
expect(res.createSetupACL5.setupACL5.acl.users).toHaveLength(0)
|
|
495
|
+
|
|
496
|
+
// Role
|
|
497
|
+
expect(
|
|
498
|
+
await getRoleNameFromId(
|
|
499
|
+
res.createSetupACL5.setupACL5.acl.roles[0].roleId,
|
|
500
|
+
rootClient,
|
|
501
|
+
),
|
|
502
|
+
).toEqual('Client')
|
|
503
|
+
|
|
504
|
+
expect(
|
|
505
|
+
await getRoleNameFromId(
|
|
506
|
+
res.createSetupACL5.setupACL5.acl.roles[1].roleId,
|
|
507
|
+
rootClient,
|
|
508
|
+
),
|
|
509
|
+
).toEqual('Client2')
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
it('should not setup acl if the acl field is already provided in the creation', async () => {
|
|
513
|
+
await rootClient.request<any>(gql`
|
|
514
|
+
mutation createSetupACL6 {
|
|
515
|
+
createSetupACL6(input: {fields: {test: "test", acl: {users: [{userId: "test", read: true, write: true}], roles: [{roleId: "test", read: true, write: true}]}}}) {
|
|
516
|
+
setupACL6 {
|
|
517
|
+
id
|
|
518
|
+
acl {
|
|
519
|
+
users {
|
|
520
|
+
userId
|
|
521
|
+
read
|
|
522
|
+
write
|
|
523
|
+
}
|
|
524
|
+
roles {
|
|
525
|
+
roleId
|
|
526
|
+
read
|
|
527
|
+
write
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
`)
|
|
534
|
+
|
|
535
|
+
const res = await rootClient.request<any>(gql`
|
|
536
|
+
query setupACLs {
|
|
537
|
+
setupACL6s{
|
|
538
|
+
edges {
|
|
539
|
+
node {
|
|
540
|
+
id
|
|
541
|
+
acl {
|
|
542
|
+
users {
|
|
543
|
+
userId
|
|
544
|
+
read
|
|
545
|
+
write
|
|
546
|
+
}
|
|
547
|
+
roles {
|
|
548
|
+
roleId
|
|
549
|
+
read
|
|
550
|
+
write
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
`)
|
|
558
|
+
|
|
559
|
+
expect(res.setupACL6s.edges[0].node.acl).toEqual({
|
|
560
|
+
users: [{ userId: 'test', read: true, write: true }],
|
|
561
|
+
roles: [{ roleId: 'test', read: true, write: true }],
|
|
562
|
+
})
|
|
563
|
+
})
|
|
564
|
+
})
|
|
565
|
+
|
|
566
|
+
const graphql = {
|
|
567
|
+
deleteUsers: gql`
|
|
568
|
+
mutation deleteUser {
|
|
569
|
+
deleteUsers(
|
|
570
|
+
input: {where: {authentication: {emailPassword: {email: {equalTo: "email@test.fr"}}}}}
|
|
571
|
+
) {
|
|
572
|
+
edges {
|
|
573
|
+
node {
|
|
574
|
+
id
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
`,
|
|
580
|
+
signUpWith: gql`
|
|
581
|
+
mutation signUpWith($input: SignUpWithInput!) {
|
|
582
|
+
signUpWith(input: $input){
|
|
583
|
+
id
|
|
584
|
+
accessToken
|
|
585
|
+
refreshToken
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
`,
|
|
589
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { HookObject } from './HookObject'
|
|
2
|
+
|
|
3
|
+
const setupAcl = async (hookObject: HookObject<any, any>) => {
|
|
4
|
+
const schemaPermissionsObject =
|
|
5
|
+
hookObject.context.wabe.config.schema?.classes?.find(
|
|
6
|
+
(c) => c.name === hookObject.className,
|
|
7
|
+
)?.permissions
|
|
8
|
+
|
|
9
|
+
if (!schemaPermissionsObject) return
|
|
10
|
+
|
|
11
|
+
const { acl } = schemaPermissionsObject
|
|
12
|
+
|
|
13
|
+
if (hookObject.isFieldUpdated('acl') || !acl) return
|
|
14
|
+
|
|
15
|
+
if (acl) await acl(hookObject)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const defaultSetupAclBeforeCreate = async (
|
|
19
|
+
hookObject: HookObject<any, any>,
|
|
20
|
+
) => {
|
|
21
|
+
// ACL on user need an update mutation not upsertNewData
|
|
22
|
+
if (hookObject.className === 'User') return
|
|
23
|
+
|
|
24
|
+
await setupAcl(hookObject)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const defaultSetupAclOnUserAfterCreate = async (
|
|
28
|
+
hookObject: HookObject<any, any>,
|
|
29
|
+
) => setupAcl(hookObject)
|
package/src/index.ts
ADDED