wabe 0.6.11 → 0.6.13
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/dist/authentication/Session.d.ts +10 -12
- package/dist/authentication/cookies.d.ts +1 -0
- package/dist/authentication/index.d.ts +1 -0
- package/dist/authentication/interface.d.ts +20 -0
- package/dist/authentication/security.d.ts +18 -0
- package/dist/database/DatabaseController.d.ts +57 -3
- package/dist/database/interface.d.ts +5 -0
- package/dist/file/interface.d.ts +23 -0
- package/dist/file/security.d.ts +6 -0
- package/dist/graphql/GraphQLSchema.d.ts +1 -1
- package/dist/graphql/resolvers.d.ts +1 -0
- package/dist/hooks/protected.d.ts +3 -0
- package/dist/hooks/virtualFields.d.ts +3 -0
- package/dist/index.js +1757 -818
- package/dist/schema/Schema.d.ts +66 -7
- package/dist/server/index.d.ts +2 -1
- package/dist/server/routes/index.d.ts +4 -1
- package/dist/utils/database.d.ts +1 -0
- package/dist/utils/export.d.ts +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/package.json +7 -4
- package/bucket/b.txt +0 -1
- package/dev/index.ts +0 -215
- package/generated/schema.graphql +0 -1892
- package/generated/wabe.ts +0 -439
- package/src/authentication/OTP.test.ts +0 -69
- package/src/authentication/OTP.ts +0 -64
- package/src/authentication/Session.test.ts +0 -629
- package/src/authentication/Session.ts +0 -493
- package/src/authentication/defaultAuthentication.ts +0 -209
- package/src/authentication/index.ts +0 -3
- package/src/authentication/interface.ts +0 -155
- package/src/authentication/oauth/GitHub.test.ts +0 -91
- package/src/authentication/oauth/GitHub.ts +0 -121
- package/src/authentication/oauth/Google.test.ts +0 -91
- package/src/authentication/oauth/Google.ts +0 -101
- package/src/authentication/oauth/Oauth2Client.test.ts +0 -219
- package/src/authentication/oauth/Oauth2Client.ts +0 -135
- package/src/authentication/oauth/index.ts +0 -2
- package/src/authentication/oauth/utils.test.ts +0 -33
- package/src/authentication/oauth/utils.ts +0 -27
- package/src/authentication/providers/EmailOTP.test.ts +0 -127
- package/src/authentication/providers/EmailOTP.ts +0 -84
- package/src/authentication/providers/EmailPassword.test.ts +0 -176
- package/src/authentication/providers/EmailPassword.ts +0 -116
- package/src/authentication/providers/EmailPasswordSRP.test.ts +0 -208
- package/src/authentication/providers/EmailPasswordSRP.ts +0 -179
- package/src/authentication/providers/GitHub.ts +0 -24
- package/src/authentication/providers/Google.ts +0 -24
- package/src/authentication/providers/OAuth.test.ts +0 -185
- package/src/authentication/providers/OAuth.ts +0 -106
- package/src/authentication/providers/PhonePassword.test.ts +0 -176
- package/src/authentication/providers/PhonePassword.ts +0 -115
- package/src/authentication/providers/QRCodeOTP.test.ts +0 -77
- package/src/authentication/providers/QRCodeOTP.ts +0 -58
- package/src/authentication/providers/index.ts +0 -6
- package/src/authentication/resolvers/refreshResolver.test.ts +0 -30
- package/src/authentication/resolvers/refreshResolver.ts +0 -19
- package/src/authentication/resolvers/signInWithResolver.inte.test.ts +0 -59
- package/src/authentication/resolvers/signInWithResolver.test.ts +0 -293
- package/src/authentication/resolvers/signInWithResolver.ts +0 -92
- package/src/authentication/resolvers/signOutResolver.test.ts +0 -38
- package/src/authentication/resolvers/signOutResolver.ts +0 -18
- package/src/authentication/resolvers/signUpWithResolver.test.ts +0 -180
- package/src/authentication/resolvers/signUpWithResolver.ts +0 -65
- package/src/authentication/resolvers/verifyChallenge.test.ts +0 -133
- package/src/authentication/resolvers/verifyChallenge.ts +0 -62
- package/src/authentication/roles.test.ts +0 -49
- package/src/authentication/roles.ts +0 -40
- package/src/authentication/utils.test.ts +0 -97
- package/src/authentication/utils.ts +0 -39
- package/src/cache/InMemoryCache.test.ts +0 -62
- package/src/cache/InMemoryCache.ts +0 -45
- package/src/cron/index.test.ts +0 -17
- package/src/cron/index.ts +0 -43
- package/src/database/DatabaseController.test.ts +0 -613
- package/src/database/DatabaseController.ts +0 -1007
- package/src/database/index.test.ts +0 -1372
- package/src/database/index.ts +0 -9
- package/src/database/interface.ts +0 -302
- package/src/email/DevAdapter.ts +0 -7
- package/src/email/EmailController.test.ts +0 -29
- package/src/email/EmailController.ts +0 -13
- package/src/email/index.ts +0 -2
- package/src/email/interface.ts +0 -36
- package/src/email/templates/sendOtpCode.ts +0 -120
- package/src/file/FileController.ts +0 -28
- package/src/file/FileDevAdapter.ts +0 -51
- package/src/file/hookDeleteFile.ts +0 -25
- package/src/file/hookReadFile.ts +0 -66
- package/src/file/hookUploadFile.ts +0 -50
- package/src/file/index.test.ts +0 -932
- package/src/file/index.ts +0 -2
- package/src/file/interface.ts +0 -39
- package/src/graphql/GraphQLSchema.test.ts +0 -4408
- package/src/graphql/GraphQLSchema.ts +0 -880
- package/src/graphql/index.ts +0 -2
- package/src/graphql/parseGraphqlSchema.ts +0 -85
- package/src/graphql/parser.test.ts +0 -203
- package/src/graphql/parser.ts +0 -542
- package/src/graphql/pointerAndRelationFunction.ts +0 -191
- package/src/graphql/resolvers.ts +0 -442
- package/src/graphql/tests/aggregation.test.ts +0 -1115
- package/src/graphql/tests/e2e.test.ts +0 -590
- package/src/graphql/tests/scalars.test.ts +0 -250
- package/src/graphql/types.ts +0 -227
- package/src/hooks/HookObject.test.ts +0 -122
- package/src/hooks/HookObject.ts +0 -165
- package/src/hooks/authentication.ts +0 -67
- package/src/hooks/createUser.test.ts +0 -77
- package/src/hooks/createUser.ts +0 -10
- package/src/hooks/defaultFields.test.ts +0 -176
- package/src/hooks/defaultFields.ts +0 -32
- package/src/hooks/deleteSession.test.ts +0 -181
- package/src/hooks/deleteSession.ts +0 -20
- package/src/hooks/hashFieldHook.test.ts +0 -152
- package/src/hooks/hashFieldHook.ts +0 -89
- package/src/hooks/index.test.ts +0 -258
- package/src/hooks/index.ts +0 -414
- package/src/hooks/permissions.test.ts +0 -412
- package/src/hooks/permissions.ts +0 -93
- package/src/hooks/protected.test.ts +0 -551
- package/src/hooks/protected.ts +0 -60
- package/src/hooks/searchableFields.test.ts +0 -147
- package/src/hooks/searchableFields.ts +0 -86
- package/src/hooks/session.test.ts +0 -134
- package/src/hooks/session.ts +0 -76
- package/src/hooks/setEmail.test.ts +0 -216
- package/src/hooks/setEmail.ts +0 -33
- package/src/hooks/setupAcl.test.ts +0 -618
- package/src/hooks/setupAcl.ts +0 -25
- package/src/index.ts +0 -9
- package/src/schema/Schema.test.ts +0 -482
- package/src/schema/Schema.ts +0 -757
- package/src/schema/defaultResolvers.ts +0 -93
- package/src/schema/index.ts +0 -1
- package/src/schema/resolvers/meResolver.test.ts +0 -62
- package/src/schema/resolvers/meResolver.ts +0 -10
- package/src/schema/resolvers/resetPassword.test.ts +0 -341
- package/src/schema/resolvers/resetPassword.ts +0 -63
- package/src/schema/resolvers/sendEmail.test.ts +0 -118
- package/src/schema/resolvers/sendEmail.ts +0 -21
- package/src/schema/resolvers/sendOtpCode.test.ts +0 -141
- package/src/schema/resolvers/sendOtpCode.ts +0 -52
- package/src/security.test.ts +0 -3434
- package/src/server/defaultSessionHandler.test.ts +0 -62
- package/src/server/defaultSessionHandler.ts +0 -105
- package/src/server/generateCodegen.ts +0 -433
- package/src/server/index.test.ts +0 -532
- package/src/server/index.ts +0 -334
- package/src/server/interface.ts +0 -11
- package/src/server/routes/authHandler.ts +0 -169
- package/src/server/routes/index.ts +0 -39
- package/src/utils/crypto.test.ts +0 -41
- package/src/utils/crypto.ts +0 -105
- package/src/utils/export.ts +0 -11
- package/src/utils/helper.ts +0 -204
- package/src/utils/index.test.ts +0 -11
- package/src/utils/index.ts +0 -189
- package/src/utils/preload.ts +0 -8
- package/src/utils/testHelper.ts +0 -116
- package/tsconfig.json +0 -32
package/src/hooks/HookObject.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import type { OperationType } from '.'
|
|
2
|
-
import type { RoleEnum, ACLObject } from '../../generated/wabe'
|
|
3
|
-
import type { MutationData, OutputType, Select } from '../database'
|
|
4
|
-
import type { WabeTypes } from '../server'
|
|
5
|
-
import type { WabeContext } from '../server/interface'
|
|
6
|
-
import { contextWithRoot } from '../utils/export'
|
|
7
|
-
|
|
8
|
-
type AddACLOpptions = {
|
|
9
|
-
userId?: string
|
|
10
|
-
role?: RoleEnum
|
|
11
|
-
read: boolean
|
|
12
|
-
write: boolean
|
|
13
|
-
} | null
|
|
14
|
-
|
|
15
|
-
export class HookObject<T extends WabeTypes, K extends keyof WabeTypes['types']> {
|
|
16
|
-
public className: K
|
|
17
|
-
private newData: MutationData<T, K, keyof T['types'][K]> | undefined
|
|
18
|
-
public operationType: OperationType
|
|
19
|
-
public context: WabeContext<T>
|
|
20
|
-
public object: OutputType<T, K, keyof T['types'][K]>
|
|
21
|
-
// Object before any mutation, for example before delete
|
|
22
|
-
public originalObject: OutputType<T, K, keyof T['types'][K]> | undefined
|
|
23
|
-
public select: Select
|
|
24
|
-
|
|
25
|
-
constructor({
|
|
26
|
-
newData,
|
|
27
|
-
className,
|
|
28
|
-
operationType,
|
|
29
|
-
context,
|
|
30
|
-
object,
|
|
31
|
-
originalObject,
|
|
32
|
-
select,
|
|
33
|
-
}: {
|
|
34
|
-
className: K
|
|
35
|
-
newData?: MutationData<T, K, keyof T['types'][K]>
|
|
36
|
-
operationType: OperationType
|
|
37
|
-
context: WabeContext<T>
|
|
38
|
-
object: OutputType<T, K, keyof T['types'][K]>
|
|
39
|
-
originalObject?: OutputType<T, K, keyof T['types'][K]>
|
|
40
|
-
select: Select
|
|
41
|
-
}) {
|
|
42
|
-
this.newData = newData
|
|
43
|
-
this.className = className
|
|
44
|
-
this.operationType = operationType
|
|
45
|
-
this.context = context
|
|
46
|
-
this.object = object
|
|
47
|
-
this.originalObject = originalObject
|
|
48
|
-
this.select = select || {}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
getUser() {
|
|
52
|
-
return this.context.user
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
isFieldUpdated(field: keyof T['types'][K]) {
|
|
56
|
-
return !!(this.newData && !!this.newData[field])
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
upsertNewData(field: keyof T['types'][K], value: any) {
|
|
60
|
-
if (!this.newData) return
|
|
61
|
-
|
|
62
|
-
if (!['beforeCreate', 'beforeUpdate'].includes(this.operationType))
|
|
63
|
-
throw new Error('Cannot set data in a hook that is not a before hook')
|
|
64
|
-
|
|
65
|
-
this.newData[field] = value
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
getNewData(): MutationData<T, K, keyof T['types'][K]> {
|
|
69
|
-
return this.newData || ({} as any)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
fetch(): Promise<OutputType<T, K, keyof T['types'][K]>> {
|
|
73
|
-
const databaseController = this.context.wabe.controllers.database
|
|
74
|
-
|
|
75
|
-
if (!this.object?.id) return Promise.resolve(null)
|
|
76
|
-
|
|
77
|
-
return databaseController.getObject({
|
|
78
|
-
className: this.className,
|
|
79
|
-
id: this.object.id,
|
|
80
|
-
context: contextWithRoot(this.context),
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async addACL(type: 'users' | 'roles', options: AddACLOpptions) {
|
|
85
|
-
const updateACL = async (newACLObject: any) => {
|
|
86
|
-
if (this.className === 'User') {
|
|
87
|
-
const currentUserId = this.object?.id
|
|
88
|
-
|
|
89
|
-
if (currentUserId)
|
|
90
|
-
await this.context.wabe.controllers.database.updateObject({
|
|
91
|
-
className: this.className,
|
|
92
|
-
context: contextWithRoot(this.context),
|
|
93
|
-
id: currentUserId,
|
|
94
|
-
data: {
|
|
95
|
-
// @ts-expect-error
|
|
96
|
-
acl: newACLObject,
|
|
97
|
-
},
|
|
98
|
-
select: {},
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// @ts-expect-error
|
|
105
|
-
this.upsertNewData('acl', newACLObject)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const result =
|
|
109
|
-
this.className === 'User'
|
|
110
|
-
? await this.context.wabe.controllers.database.getObject({
|
|
111
|
-
className: 'User',
|
|
112
|
-
// @ts-expect-error
|
|
113
|
-
select: { acl: true },
|
|
114
|
-
// @ts-expect-error
|
|
115
|
-
id: this.object?.id,
|
|
116
|
-
context: contextWithRoot(this.context),
|
|
117
|
-
})
|
|
118
|
-
: // @ts-expect-error
|
|
119
|
-
{ acl: this.getNewData().acl }
|
|
120
|
-
|
|
121
|
-
const currentACL: ACLObject = result?.acl || {}
|
|
122
|
-
|
|
123
|
-
if (options === null) {
|
|
124
|
-
await updateACL({
|
|
125
|
-
...currentACL,
|
|
126
|
-
[type]: [],
|
|
127
|
-
})
|
|
128
|
-
return
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const { userId, role, read, write } = options
|
|
132
|
-
|
|
133
|
-
if (userId && role) throw new Error('Cannot specify both userId and role')
|
|
134
|
-
|
|
135
|
-
if (role) {
|
|
136
|
-
const result = await this.context.wabe.controllers.database.getObjects({
|
|
137
|
-
className: 'Role',
|
|
138
|
-
// @ts-expect-error
|
|
139
|
-
select: { id: true },
|
|
140
|
-
// @ts-expect-error
|
|
141
|
-
where: {
|
|
142
|
-
name: {
|
|
143
|
-
equalTo: role,
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
context: contextWithRoot(this.context),
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
const roleId = result[0]?.id
|
|
150
|
-
|
|
151
|
-
await updateACL({
|
|
152
|
-
...currentACL,
|
|
153
|
-
[type]: [...(currentACL?.[type] || []), { roleId, read, write }],
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// User ACL
|
|
160
|
-
await updateACL({
|
|
161
|
-
...currentACL,
|
|
162
|
-
[type]: [...(currentACL?.[type] || []), { userId, read, write }],
|
|
163
|
-
})
|
|
164
|
-
}
|
|
165
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import type { ProviderInterface } from '../authentication'
|
|
2
|
-
import { getAuthenticationMethod } from '../authentication/utils'
|
|
3
|
-
import type { DevWabeTypes } from '../utils/helper'
|
|
4
|
-
import type { HookObject } from './HookObject'
|
|
5
|
-
|
|
6
|
-
export const defaultCallAuthenticationProviderOnBeforeCreateUser = async (
|
|
7
|
-
hookObject: HookObject<any, any>,
|
|
8
|
-
) => {
|
|
9
|
-
if (!hookObject.isFieldUpdated('authentication') || hookObject.getNewData().isOauth) return
|
|
10
|
-
|
|
11
|
-
const context = hookObject.context
|
|
12
|
-
|
|
13
|
-
const authentication = hookObject.getNewData().authentication
|
|
14
|
-
|
|
15
|
-
// Exception for SRP
|
|
16
|
-
if (authentication.emailPasswordSRP) return
|
|
17
|
-
|
|
18
|
-
const { provider, name } = getAuthenticationMethod<DevWabeTypes, ProviderInterface<DevWabeTypes>>(
|
|
19
|
-
Object.keys(authentication),
|
|
20
|
-
context,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
const inputOfTheGoodAuthenticationMethod = authentication[name]
|
|
24
|
-
|
|
25
|
-
const { authenticationDataToSave } = await provider.onSignUp({
|
|
26
|
-
input: inputOfTheGoodAuthenticationMethod,
|
|
27
|
-
context,
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
hookObject.upsertNewData('authentication', {
|
|
31
|
-
[name]: authenticationDataToSave,
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const defaultCallAuthenticationProviderOnBeforeUpdateUser = async (
|
|
36
|
-
hookObject: HookObject<any, any>,
|
|
37
|
-
) => {
|
|
38
|
-
if (!hookObject.isFieldUpdated('authentication') || hookObject.getNewData().isOauth) return
|
|
39
|
-
|
|
40
|
-
const context = hookObject.context
|
|
41
|
-
|
|
42
|
-
const authentication = hookObject.getNewData().authentication
|
|
43
|
-
|
|
44
|
-
// Exception for SRP
|
|
45
|
-
if (authentication.emailPasswordSRP) return
|
|
46
|
-
|
|
47
|
-
const { provider, name } = getAuthenticationMethod<DevWabeTypes, ProviderInterface<DevWabeTypes>>(
|
|
48
|
-
Object.keys(authentication),
|
|
49
|
-
context,
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
if (!provider.onUpdateAuthenticationData) return
|
|
53
|
-
|
|
54
|
-
const inputOfTheGoodAuthenticationMethod = authentication[name]
|
|
55
|
-
|
|
56
|
-
if (!hookObject.object?.id) return
|
|
57
|
-
|
|
58
|
-
const { authenticationDataToSave } = await provider.onUpdateAuthenticationData({
|
|
59
|
-
context,
|
|
60
|
-
input: inputOfTheGoodAuthenticationMethod,
|
|
61
|
-
userId: hookObject.object.id,
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
hookObject.upsertNewData('authentication', {
|
|
65
|
-
[name]: authenticationDataToSave,
|
|
66
|
-
})
|
|
67
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { describe, beforeAll, afterAll, afterEach, it, expect } from 'bun:test'
|
|
2
|
-
import type { Wabe } from 'src'
|
|
3
|
-
import type { DevWabeTypes } from 'src/utils/helper'
|
|
4
|
-
import { setupTests, closeTests } from 'src/utils/testHelper'
|
|
5
|
-
|
|
6
|
-
describe('createUser hook', () => {
|
|
7
|
-
let wabe: Wabe<DevWabeTypes>
|
|
8
|
-
|
|
9
|
-
beforeAll(async () => {
|
|
10
|
-
const setup = await setupTests()
|
|
11
|
-
wabe = setup.wabe
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
afterAll(async () => {
|
|
15
|
-
await closeTests(wabe)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
afterEach(async () => {
|
|
19
|
-
await wabe.controllers.database.clearDatabase()
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('should throw an error if disableSignUp is true and user is anonymous', () => {
|
|
23
|
-
if (wabe.config) {
|
|
24
|
-
wabe.config.authentication = {
|
|
25
|
-
disableSignUp: true,
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
expect(
|
|
30
|
-
wabe.controllers.database.createObject({
|
|
31
|
-
className: 'User',
|
|
32
|
-
context: {
|
|
33
|
-
wabe,
|
|
34
|
-
isRoot: false,
|
|
35
|
-
},
|
|
36
|
-
data: {
|
|
37
|
-
email: 'email@test.fr',
|
|
38
|
-
},
|
|
39
|
-
select: {},
|
|
40
|
-
}),
|
|
41
|
-
).rejects.toThrow('Sign up is disabled')
|
|
42
|
-
|
|
43
|
-
if (wabe.config) {
|
|
44
|
-
wabe.config.authentication = {
|
|
45
|
-
disableSignUp: false,
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('should not throw an error if disableSignUp is true and user is root', async () => {
|
|
51
|
-
if (wabe.config) {
|
|
52
|
-
wabe.config.authentication = {
|
|
53
|
-
disableSignUp: true,
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const res = await wabe.controllers.database.createObject({
|
|
58
|
-
className: 'User',
|
|
59
|
-
context: {
|
|
60
|
-
wabe,
|
|
61
|
-
isRoot: true,
|
|
62
|
-
},
|
|
63
|
-
data: {
|
|
64
|
-
email: 'email@test.fr',
|
|
65
|
-
},
|
|
66
|
-
select: { id: true },
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
expect(res?.id).toBeDefined()
|
|
70
|
-
|
|
71
|
-
if (wabe.config) {
|
|
72
|
-
wabe.config.authentication = {
|
|
73
|
-
disableSignUp: false,
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
})
|
package/src/hooks/createUser.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { HookObject } from './HookObject'
|
|
2
|
-
|
|
3
|
-
export const defaultBeforeCreateUser = (object: HookObject<any, any>) => {
|
|
4
|
-
const context = object.context
|
|
5
|
-
|
|
6
|
-
if (context.isRoot) return
|
|
7
|
-
|
|
8
|
-
if (context.wabe.config.authentication?.disableSignUp && !context.user)
|
|
9
|
-
throw new Error('Sign up is disabled')
|
|
10
|
-
}
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, spyOn } from 'bun:test'
|
|
2
|
-
import {
|
|
3
|
-
defaultBeforeCreateForCreatedAt,
|
|
4
|
-
defaultBeforeCreateForDefaultValue,
|
|
5
|
-
defaultBeforeUpdateForUpdatedAt,
|
|
6
|
-
} from './defaultFields'
|
|
7
|
-
import { HookObject } from './HookObject'
|
|
8
|
-
import { OperationType } from '.'
|
|
9
|
-
import type { DevWabeTypes } from '../utils/helper'
|
|
10
|
-
|
|
11
|
-
describe('Default fields', () => {
|
|
12
|
-
const now = new Date()
|
|
13
|
-
|
|
14
|
-
describe('CreatedAt and UpdatedAt', () => {
|
|
15
|
-
it('should add createdAt and updatedAt value on insert operation type', () => {
|
|
16
|
-
const hookObject = new HookObject<DevWabeTypes, 'User'>({
|
|
17
|
-
className: 'User',
|
|
18
|
-
operationType: OperationType.BeforeCreate,
|
|
19
|
-
newData: {
|
|
20
|
-
email: 'email@test.fr',
|
|
21
|
-
} as any,
|
|
22
|
-
context: {} as any,
|
|
23
|
-
object: {} as any,
|
|
24
|
-
select: {},
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const spyHookObjectUpsertNewData = spyOn(hookObject, 'upsertNewData')
|
|
28
|
-
|
|
29
|
-
defaultBeforeCreateForCreatedAt(hookObject)
|
|
30
|
-
|
|
31
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenCalledTimes(2)
|
|
32
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenNthCalledWith(1, 'createdAt', expect.any(Date))
|
|
33
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenNthCalledWith(2, 'updatedAt', expect.any(Date))
|
|
34
|
-
|
|
35
|
-
const createdAt = spyHookObjectUpsertNewData.mock.calls[0]?.[1]
|
|
36
|
-
|
|
37
|
-
expect(createdAt.getDay()).toEqual(now.getDay())
|
|
38
|
-
expect(createdAt.getMonth()).toEqual(now.getMonth())
|
|
39
|
-
expect(createdAt.getFullYear()).toEqual(now.getFullYear())
|
|
40
|
-
|
|
41
|
-
const updatedAt = spyHookObjectUpsertNewData.mock.calls[1]?.[1]
|
|
42
|
-
expect(updatedAt.getDay()).toEqual(now.getDay())
|
|
43
|
-
expect(updatedAt.getMonth()).toEqual(now.getMonth())
|
|
44
|
-
expect(updatedAt.getFullYear()).toEqual(now.getFullYear())
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should add updatedAt value on update operation type', () => {
|
|
48
|
-
const hookObject = new HookObject<DevWabeTypes, 'User'>({
|
|
49
|
-
className: 'User',
|
|
50
|
-
operationType: OperationType.BeforeUpdate,
|
|
51
|
-
newData: {
|
|
52
|
-
email: 'email@test.fr',
|
|
53
|
-
} as any,
|
|
54
|
-
context: {} as any,
|
|
55
|
-
object: {} as any,
|
|
56
|
-
select: {},
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
const spyHookObjectUpsertNewData = spyOn(hookObject, 'upsertNewData')
|
|
60
|
-
|
|
61
|
-
defaultBeforeUpdateForUpdatedAt(hookObject)
|
|
62
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenCalledTimes(1)
|
|
63
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenCalledWith('updatedAt', expect.any(Date))
|
|
64
|
-
|
|
65
|
-
const updatedAt = spyHookObjectUpsertNewData.mock.calls[0]?.[1]
|
|
66
|
-
|
|
67
|
-
// Don't test hours to avoid flaky
|
|
68
|
-
expect(updatedAt.getDay()).toEqual(now.getDay())
|
|
69
|
-
expect(updatedAt.getMonth()).toEqual(now.getMonth())
|
|
70
|
-
expect(updatedAt.getFullYear()).toEqual(now.getFullYear())
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('should not overwrite if the createdAt field is already set', () => {
|
|
74
|
-
const hookObject = new HookObject<DevWabeTypes, 'User'>({
|
|
75
|
-
className: 'User',
|
|
76
|
-
operationType: OperationType.BeforeCreate,
|
|
77
|
-
newData: {
|
|
78
|
-
email: 'email@test.fr',
|
|
79
|
-
createdAt: now,
|
|
80
|
-
} as any,
|
|
81
|
-
context: {} as any,
|
|
82
|
-
object: {} as any,
|
|
83
|
-
select: {},
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
const spyHookObjectUpsertNewData = spyOn(hookObject, 'upsertNewData')
|
|
87
|
-
|
|
88
|
-
defaultBeforeCreateForCreatedAt(hookObject)
|
|
89
|
-
|
|
90
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenCalledTimes(1)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('should not overwrite if the updatedAt field is already set', () => {
|
|
94
|
-
const hookObject = new HookObject<DevWabeTypes, 'User'>({
|
|
95
|
-
className: 'User',
|
|
96
|
-
operationType: OperationType.BeforeCreate,
|
|
97
|
-
newData: {
|
|
98
|
-
email: 'email@test.fr',
|
|
99
|
-
updatedAt: now,
|
|
100
|
-
} as any,
|
|
101
|
-
context: {} as any,
|
|
102
|
-
object: {} as any,
|
|
103
|
-
select: {},
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
const spyHookObjectUpsertNewData = spyOn(hookObject, 'upsertNewData')
|
|
107
|
-
|
|
108
|
-
defaultBeforeCreateForCreatedAt(hookObject)
|
|
109
|
-
|
|
110
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenCalledTimes(1)
|
|
111
|
-
})
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
describe('Default value', () => {
|
|
115
|
-
const config = {
|
|
116
|
-
schema: {
|
|
117
|
-
classes: [
|
|
118
|
-
{
|
|
119
|
-
name: 'User',
|
|
120
|
-
fields: {
|
|
121
|
-
name: { type: 'String' },
|
|
122
|
-
age: { type: 'Int' },
|
|
123
|
-
isAdmin: {
|
|
124
|
-
type: 'Boolean',
|
|
125
|
-
defaultValue: false,
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
},
|
|
131
|
-
} as any
|
|
132
|
-
|
|
133
|
-
const context = { wabe: { config } } as any
|
|
134
|
-
|
|
135
|
-
it('should add the value if a default value is defined in schema but not specified', async () => {
|
|
136
|
-
const hookObject = new HookObject<DevWabeTypes, 'User'>({
|
|
137
|
-
className: 'User',
|
|
138
|
-
operationType: OperationType.BeforeCreate,
|
|
139
|
-
newData: {
|
|
140
|
-
id: 'id',
|
|
141
|
-
email: 'email@test.fr',
|
|
142
|
-
} as any,
|
|
143
|
-
context,
|
|
144
|
-
object: {} as any,
|
|
145
|
-
select: {},
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
const spyHookObjectUpsertNewData = spyOn(hookObject, 'upsertNewData')
|
|
149
|
-
|
|
150
|
-
await defaultBeforeCreateForDefaultValue(hookObject)
|
|
151
|
-
|
|
152
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenCalledTimes(1)
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
it('should not add a default value if a value is specified', async () => {
|
|
156
|
-
const hookObject = new HookObject<DevWabeTypes, 'User'>({
|
|
157
|
-
className: 'User',
|
|
158
|
-
operationType: OperationType.BeforeCreate,
|
|
159
|
-
newData: {
|
|
160
|
-
id: 'id',
|
|
161
|
-
email: 'email@test.fr',
|
|
162
|
-
isAdmin: true,
|
|
163
|
-
} as any,
|
|
164
|
-
context,
|
|
165
|
-
object: {} as any,
|
|
166
|
-
select: {},
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
const spyHookObjectUpsertNewData = spyOn(hookObject, 'upsertNewData')
|
|
170
|
-
|
|
171
|
-
await defaultBeforeCreateForDefaultValue(hookObject)
|
|
172
|
-
|
|
173
|
-
expect(spyHookObjectUpsertNewData).toHaveBeenCalledTimes(0)
|
|
174
|
-
})
|
|
175
|
-
})
|
|
176
|
-
})
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { getClassFromClassName } from '../utils'
|
|
2
|
-
import type { DevWabeTypes } from '../utils/helper'
|
|
3
|
-
import type { HookObject } from './HookObject'
|
|
4
|
-
|
|
5
|
-
export const defaultBeforeCreateForCreatedAt = (object: HookObject<any, any>) => {
|
|
6
|
-
if (!object.isFieldUpdated('createdAt')) object.upsertNewData('createdAt', new Date())
|
|
7
|
-
|
|
8
|
-
if (!object.isFieldUpdated('updatedAt')) object.upsertNewData('updatedAt', new Date())
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const defaultBeforeUpdateForUpdatedAt = (object: HookObject<any, any>) => {
|
|
12
|
-
object.upsertNewData('updatedAt', new Date())
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const defaultBeforeCreateForDefaultValue = (object: HookObject<any, any>) => {
|
|
16
|
-
const schemaClass = getClassFromClassName<DevWabeTypes>(
|
|
17
|
-
object.className,
|
|
18
|
-
object.context.wabe.config,
|
|
19
|
-
)
|
|
20
|
-
const allFields = Object.keys(schemaClass.fields)
|
|
21
|
-
allFields.forEach((field) => {
|
|
22
|
-
const currentSchemaField = schemaClass.fields[field]
|
|
23
|
-
if (
|
|
24
|
-
!object.isFieldUpdated(field) &&
|
|
25
|
-
currentSchemaField?.type !== 'Pointer' &&
|
|
26
|
-
currentSchemaField?.type !== 'Relation' &&
|
|
27
|
-
currentSchemaField?.type !== 'File' &&
|
|
28
|
-
currentSchemaField?.defaultValue !== undefined
|
|
29
|
-
)
|
|
30
|
-
object.upsertNewData(field, currentSchemaField.defaultValue)
|
|
31
|
-
})
|
|
32
|
-
}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { describe, beforeAll, afterAll, expect, it, beforeEach } from 'bun:test'
|
|
2
|
-
import type { Wabe } from '../server'
|
|
3
|
-
import { type DevWabeTypes, getGraphqlClient } from '../utils/helper'
|
|
4
|
-
import { setupTests, closeTests } from '../utils/testHelper'
|
|
5
|
-
import { gql, type GraphQLClient } from 'graphql-request'
|
|
6
|
-
|
|
7
|
-
describe('Delete session on delete user', () => {
|
|
8
|
-
let wabe: Wabe<DevWabeTypes>
|
|
9
|
-
let port: number
|
|
10
|
-
let client: GraphQLClient
|
|
11
|
-
|
|
12
|
-
beforeAll(async () => {
|
|
13
|
-
const setup = await setupTests()
|
|
14
|
-
wabe = setup.wabe
|
|
15
|
-
port = setup.port
|
|
16
|
-
client = getGraphqlClient(port)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
afterAll(async () => {
|
|
20
|
-
await closeTests(wabe)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
beforeEach(async () => {
|
|
24
|
-
await wabe.controllers.database.clearDatabase()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should delete the session when the user is deleted', async () => {
|
|
28
|
-
const {
|
|
29
|
-
signUpWith: { id: userId },
|
|
30
|
-
} = await client.request<any>(graphql.signUpWith, {
|
|
31
|
-
input: {
|
|
32
|
-
authentication: {
|
|
33
|
-
emailPassword: {
|
|
34
|
-
email: 'email@test.fr',
|
|
35
|
-
password: 'password',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
const { _sessions: sessions1 } = await client.request<any>(graphql.sessions)
|
|
42
|
-
|
|
43
|
-
expect(sessions1.edges.length).toEqual(1)
|
|
44
|
-
|
|
45
|
-
await client.request<any>(graphql.deleteUser, {
|
|
46
|
-
input: {
|
|
47
|
-
id: userId,
|
|
48
|
-
},
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
const { _sessions: sessions2 } = await client.request<any>(graphql.sessions)
|
|
52
|
-
|
|
53
|
-
expect(sessions2.edges.length).toEqual(0)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('should only delete the sessions of the deleted user', async () => {
|
|
57
|
-
const {
|
|
58
|
-
signUpWith: { id: userId },
|
|
59
|
-
} = await client.request<any>(graphql.signUpWith, {
|
|
60
|
-
input: {
|
|
61
|
-
authentication: {
|
|
62
|
-
emailPassword: {
|
|
63
|
-
email: 'email@test.fr',
|
|
64
|
-
password: 'password',
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
await client.request<any>(graphql.signUpWith, {
|
|
71
|
-
input: {
|
|
72
|
-
authentication: {
|
|
73
|
-
emailPassword: {
|
|
74
|
-
email: 'anotherEmail@test.fr',
|
|
75
|
-
password: 'password',
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const { _sessions: sessions1 } = await client.request<any>(graphql.sessions)
|
|
82
|
-
|
|
83
|
-
expect(sessions1.edges.length).toEqual(2)
|
|
84
|
-
|
|
85
|
-
await client.request<any>(graphql.deleteUser, {
|
|
86
|
-
input: {
|
|
87
|
-
id: userId,
|
|
88
|
-
},
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
const { _sessions: sessions2 } = await client.request<any>(graphql.sessions)
|
|
92
|
-
|
|
93
|
-
expect(sessions2.edges.length).toEqual(1)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it("should not delete any session if the user doesn't have any session", async () => {
|
|
97
|
-
const {
|
|
98
|
-
signUpWith: { id: userId },
|
|
99
|
-
} = await client.request<any>(graphql.signUpWith, {
|
|
100
|
-
input: {
|
|
101
|
-
authentication: {
|
|
102
|
-
emailPassword: {
|
|
103
|
-
email: 'email@test.fr',
|
|
104
|
-
password: 'password',
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
await client.request<any>(graphql.signUpWith, {
|
|
111
|
-
input: {
|
|
112
|
-
authentication: {
|
|
113
|
-
emailPassword: {
|
|
114
|
-
email: 'anotherEmail@test.fr',
|
|
115
|
-
password: 'password',
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
await wabe.controllers.database.deleteObjects({
|
|
122
|
-
className: '_Session',
|
|
123
|
-
context: {
|
|
124
|
-
wabe,
|
|
125
|
-
isRoot: true,
|
|
126
|
-
},
|
|
127
|
-
select: {},
|
|
128
|
-
where: {
|
|
129
|
-
user: {
|
|
130
|
-
id: {
|
|
131
|
-
equalTo: userId,
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
// Delete the user
|
|
138
|
-
await client.request<any>(graphql.deleteUser, {
|
|
139
|
-
input: {
|
|
140
|
-
id: userId,
|
|
141
|
-
},
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
const { _sessions: sessions2 } = await client.request<any>(graphql.sessions)
|
|
145
|
-
|
|
146
|
-
expect(sessions2.edges.length).toEqual(1)
|
|
147
|
-
})
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
const graphql = {
|
|
151
|
-
sessions: gql`
|
|
152
|
-
query _sessions {
|
|
153
|
-
_sessions {
|
|
154
|
-
edges {
|
|
155
|
-
node {
|
|
156
|
-
id
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
`,
|
|
162
|
-
signUpWith: gql`
|
|
163
|
-
mutation signUpWith($input: SignUpWithInput!) {
|
|
164
|
-
signUpWith(input: $input) {
|
|
165
|
-
id
|
|
166
|
-
accessToken
|
|
167
|
-
refreshToken
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
`,
|
|
171
|
-
deleteUser: gql`
|
|
172
|
-
mutation deleteUser($input: DeleteUserInput!) {
|
|
173
|
-
deleteUser(input: $input) {
|
|
174
|
-
user {
|
|
175
|
-
name
|
|
176
|
-
age
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
`,
|
|
181
|
-
}
|