wabe 0.6.12 → 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.
Files changed (147) hide show
  1. package/package.json +4 -1
  2. package/dev/index.ts +0 -215
  3. package/generated/schema.graphql +0 -1945
  4. package/generated/wabe.ts +0 -448
  5. package/src/authentication/OTP.test.ts +0 -69
  6. package/src/authentication/OTP.ts +0 -64
  7. package/src/authentication/Session.test.ts +0 -629
  8. package/src/authentication/Session.ts +0 -517
  9. package/src/authentication/cookies.ts +0 -10
  10. package/src/authentication/defaultAuthentication.ts +0 -209
  11. package/src/authentication/index.ts +0 -4
  12. package/src/authentication/interface.ts +0 -177
  13. package/src/authentication/oauth/GitHub.test.ts +0 -91
  14. package/src/authentication/oauth/GitHub.ts +0 -121
  15. package/src/authentication/oauth/Google.test.ts +0 -91
  16. package/src/authentication/oauth/Google.ts +0 -101
  17. package/src/authentication/oauth/Oauth2Client.test.ts +0 -219
  18. package/src/authentication/oauth/Oauth2Client.ts +0 -135
  19. package/src/authentication/oauth/index.ts +0 -2
  20. package/src/authentication/oauth/utils.test.ts +0 -33
  21. package/src/authentication/oauth/utils.ts +0 -27
  22. package/src/authentication/providers/EmailOTP.test.ts +0 -127
  23. package/src/authentication/providers/EmailOTP.ts +0 -95
  24. package/src/authentication/providers/EmailPassword.test.ts +0 -263
  25. package/src/authentication/providers/EmailPassword.ts +0 -138
  26. package/src/authentication/providers/EmailPasswordSRP.test.ts +0 -208
  27. package/src/authentication/providers/EmailPasswordSRP.ts +0 -191
  28. package/src/authentication/providers/GitHub.ts +0 -24
  29. package/src/authentication/providers/Google.ts +0 -24
  30. package/src/authentication/providers/OAuth.test.ts +0 -185
  31. package/src/authentication/providers/OAuth.ts +0 -106
  32. package/src/authentication/providers/PhonePassword.test.ts +0 -221
  33. package/src/authentication/providers/PhonePassword.ts +0 -136
  34. package/src/authentication/providers/QRCodeOTP.test.ts +0 -77
  35. package/src/authentication/providers/QRCodeOTP.ts +0 -69
  36. package/src/authentication/providers/index.ts +0 -6
  37. package/src/authentication/resolvers/refreshResolver.test.ts +0 -30
  38. package/src/authentication/resolvers/refreshResolver.ts +0 -19
  39. package/src/authentication/resolvers/signInWithResolver.inte.test.ts +0 -59
  40. package/src/authentication/resolvers/signInWithResolver.test.ts +0 -306
  41. package/src/authentication/resolvers/signInWithResolver.ts +0 -106
  42. package/src/authentication/resolvers/signOutResolver.test.ts +0 -38
  43. package/src/authentication/resolvers/signOutResolver.ts +0 -18
  44. package/src/authentication/resolvers/signUpWithResolver.test.ts +0 -180
  45. package/src/authentication/resolvers/signUpWithResolver.ts +0 -68
  46. package/src/authentication/resolvers/verifyChallenge.test.ts +0 -230
  47. package/src/authentication/resolvers/verifyChallenge.ts +0 -78
  48. package/src/authentication/roles.test.ts +0 -49
  49. package/src/authentication/roles.ts +0 -40
  50. package/src/authentication/security.ts +0 -278
  51. package/src/authentication/utils.test.ts +0 -97
  52. package/src/authentication/utils.ts +0 -39
  53. package/src/cache/InMemoryCache.test.ts +0 -62
  54. package/src/cache/InMemoryCache.ts +0 -45
  55. package/src/cron/index.test.ts +0 -17
  56. package/src/cron/index.ts +0 -43
  57. package/src/database/DatabaseController.test.ts +0 -613
  58. package/src/database/DatabaseController.ts +0 -1415
  59. package/src/database/index.test.ts +0 -1551
  60. package/src/database/index.ts +0 -9
  61. package/src/database/interface.ts +0 -308
  62. package/src/email/DevAdapter.ts +0 -7
  63. package/src/email/EmailController.test.ts +0 -29
  64. package/src/email/EmailController.ts +0 -13
  65. package/src/email/index.ts +0 -2
  66. package/src/email/interface.ts +0 -36
  67. package/src/email/templates/sendOtpCode.ts +0 -120
  68. package/src/file/FileController.ts +0 -28
  69. package/src/file/FileDevAdapter.ts +0 -51
  70. package/src/file/hookDeleteFile.ts +0 -25
  71. package/src/file/hookReadFile.ts +0 -66
  72. package/src/file/hookUploadFile.ts +0 -52
  73. package/src/file/index.test.ts +0 -1031
  74. package/src/file/index.ts +0 -2
  75. package/src/file/interface.ts +0 -63
  76. package/src/file/security.ts +0 -156
  77. package/src/graphql/GraphQLSchema.test.ts +0 -5099
  78. package/src/graphql/GraphQLSchema.ts +0 -886
  79. package/src/graphql/index.ts +0 -2
  80. package/src/graphql/parseGraphqlSchema.ts +0 -85
  81. package/src/graphql/parser.test.ts +0 -203
  82. package/src/graphql/parser.ts +0 -707
  83. package/src/graphql/pointerAndRelationFunction.ts +0 -191
  84. package/src/graphql/resolvers.ts +0 -464
  85. package/src/graphql/tests/aggregation.test.ts +0 -1115
  86. package/src/graphql/tests/e2e.test.ts +0 -590
  87. package/src/graphql/tests/scalars.test.ts +0 -250
  88. package/src/graphql/types.ts +0 -227
  89. package/src/hooks/HookObject.test.ts +0 -122
  90. package/src/hooks/HookObject.ts +0 -165
  91. package/src/hooks/authentication.ts +0 -67
  92. package/src/hooks/createUser.test.ts +0 -77
  93. package/src/hooks/createUser.ts +0 -10
  94. package/src/hooks/defaultFields.test.ts +0 -176
  95. package/src/hooks/defaultFields.ts +0 -32
  96. package/src/hooks/deleteSession.test.ts +0 -181
  97. package/src/hooks/deleteSession.ts +0 -20
  98. package/src/hooks/hashFieldHook.test.ts +0 -152
  99. package/src/hooks/hashFieldHook.ts +0 -89
  100. package/src/hooks/index.test.ts +0 -258
  101. package/src/hooks/index.ts +0 -420
  102. package/src/hooks/permissions.test.ts +0 -412
  103. package/src/hooks/permissions.ts +0 -93
  104. package/src/hooks/protected.test.ts +0 -551
  105. package/src/hooks/protected.ts +0 -74
  106. package/src/hooks/searchableFields.test.ts +0 -147
  107. package/src/hooks/searchableFields.ts +0 -86
  108. package/src/hooks/session.test.ts +0 -134
  109. package/src/hooks/session.ts +0 -76
  110. package/src/hooks/setEmail.test.ts +0 -216
  111. package/src/hooks/setEmail.ts +0 -33
  112. package/src/hooks/setupAcl.test.ts +0 -618
  113. package/src/hooks/setupAcl.ts +0 -25
  114. package/src/hooks/virtualFields.test.ts +0 -228
  115. package/src/hooks/virtualFields.ts +0 -48
  116. package/src/index.ts +0 -9
  117. package/src/schema/Schema.test.ts +0 -482
  118. package/src/schema/Schema.ts +0 -839
  119. package/src/schema/defaultResolvers.ts +0 -93
  120. package/src/schema/index.ts +0 -1
  121. package/src/schema/resolvers/meResolver.test.ts +0 -62
  122. package/src/schema/resolvers/meResolver.ts +0 -10
  123. package/src/schema/resolvers/resetPassword.test.ts +0 -341
  124. package/src/schema/resolvers/resetPassword.ts +0 -63
  125. package/src/schema/resolvers/sendEmail.test.ts +0 -118
  126. package/src/schema/resolvers/sendEmail.ts +0 -21
  127. package/src/schema/resolvers/sendOtpCode.test.ts +0 -141
  128. package/src/schema/resolvers/sendOtpCode.ts +0 -52
  129. package/src/security.test.ts +0 -4136
  130. package/src/server/defaultSessionHandler.test.ts +0 -62
  131. package/src/server/defaultSessionHandler.ts +0 -104
  132. package/src/server/generateCodegen.ts +0 -433
  133. package/src/server/index.test.ts +0 -843
  134. package/src/server/index.ts +0 -336
  135. package/src/server/interface.ts +0 -11
  136. package/src/server/routes/authHandler.ts +0 -171
  137. package/src/server/routes/index.ts +0 -48
  138. package/src/utils/crypto.test.ts +0 -41
  139. package/src/utils/crypto.ts +0 -105
  140. package/src/utils/database.ts +0 -8
  141. package/src/utils/export.ts +0 -12
  142. package/src/utils/helper.ts +0 -204
  143. package/src/utils/index.test.ts +0 -11
  144. package/src/utils/index.ts +0 -196
  145. package/src/utils/preload.ts +0 -8
  146. package/src/utils/testHelper.ts +0 -124
  147. package/tsconfig.json +0 -32
@@ -1,221 +0,0 @@
1
- import { describe, expect, it, mock, spyOn, afterEach, afterAll } from 'bun:test'
2
- import * as crypto from '../../utils/crypto'
3
-
4
- import { PhonePassword } from './PhonePassword'
5
-
6
- describe('Phone password', () => {
7
- const mockGetObject = mock(() => Promise.resolve(null)) as any
8
- const mockGetObjects = mock(() => Promise.resolve([]))
9
- const mockCount = mock(() => Promise.resolve(0)) as any
10
- const mockCreateObject = mock(() => Promise.resolve({ id: 'userId' })) as any
11
-
12
- const spyArgonPasswordVerify = spyOn(crypto, 'verifyArgon2')
13
- const spyBunPasswordHash = spyOn(crypto, 'hashArgon2')
14
-
15
- const controllers = {
16
- controllers: {
17
- database: {
18
- getObject: mockGetObject,
19
- getObjects: mockGetObjects,
20
- createObject: mockCreateObject,
21
- count: mockCount,
22
- },
23
- },
24
- } as any
25
-
26
- afterEach(() => {
27
- mockGetObject.mockClear()
28
- mockGetObjects.mockClear()
29
- mockCount.mockClear()
30
- mockCreateObject.mockClear()
31
- spyArgonPasswordVerify.mockClear()
32
- spyBunPasswordHash.mockClear()
33
- })
34
-
35
- afterAll(() => {
36
- spyArgonPasswordVerify.mockRestore()
37
- spyBunPasswordHash.mockRestore()
38
- })
39
-
40
- const phonePassword = new PhonePassword()
41
-
42
- it('should signUp with phone password', async () => {
43
- spyBunPasswordHash.mockResolvedValueOnce('$argon2id$hashedPassword')
44
-
45
- const {
46
- authenticationDataToSave: { phone },
47
- } = await phonePassword.onSignUp({
48
- context: { wabe: controllers } as any,
49
- input: { phone: 'phone@test.fr', password: 'password' },
50
- })
51
-
52
- expect(phone).toBe('phone@test.fr')
53
- })
54
-
55
- it('should signIn with phone password', async () => {
56
- mockGetObjects.mockResolvedValue([
57
- {
58
- id: 'userId',
59
- authentication: {
60
- phonePassword: {
61
- phone: 'phone@test.fr',
62
- password: 'hashedPassword',
63
- },
64
- },
65
- } as never,
66
- ])
67
-
68
- spyArgonPasswordVerify.mockResolvedValueOnce(true)
69
-
70
- const { user } = await phonePassword.onSignIn({
71
- context: { wabe: controllers } as any,
72
- input: { phone: 'phone@test.fr', password: 'password' },
73
- })
74
-
75
- expect(user).toEqual({
76
- id: 'userId',
77
- authentication: {
78
- phonePassword: {
79
- phone: 'phone@test.fr',
80
- password: 'hashedPassword',
81
- },
82
- },
83
- })
84
-
85
- expect(spyArgonPasswordVerify).toHaveBeenCalledTimes(1)
86
- expect(spyArgonPasswordVerify).toHaveBeenCalledWith('password', 'hashedPassword')
87
- })
88
-
89
- it('should not signIn with phone password if password is undefined', () => {
90
- spyArgonPasswordVerify.mockResolvedValueOnce(false)
91
-
92
- expect(
93
- phonePassword.onSignIn({
94
- context: { wabe: controllers } as any,
95
- // @ts-expect-error
96
- input: { phone: 'phone@test.fr' },
97
- }),
98
- ).rejects.toThrow('Invalid authentication credentials')
99
- })
100
-
101
- it('should not signIn with phone password if there is no user found', () => {
102
- mockGetObjects.mockResolvedValue([])
103
-
104
- expect(
105
- phonePassword.onSignIn({
106
- context: { wabe: controllers } as any,
107
- input: {
108
- phone: 'invalidEmail@test.fr',
109
- password: 'password',
110
- },
111
- }),
112
- ).rejects.toThrow('Invalid authentication credentials')
113
-
114
- expect(spyArgonPasswordVerify).toHaveBeenCalledTimes(1)
115
- })
116
-
117
- it('should not signIn with phone password if there is phone is invalid', () => {
118
- mockGetObjects.mockResolvedValue([
119
- {
120
- authentication: {
121
- phonePassword: {
122
- password: 'hashedPassword',
123
- },
124
- },
125
- } as never,
126
- ])
127
-
128
- spyArgonPasswordVerify.mockResolvedValueOnce(true)
129
-
130
- expect(
131
- phonePassword.onSignIn({
132
- context: { wabe: controllers } as any,
133
- input: {
134
- phone: 'invalidEmail@test.fr',
135
- password: 'password',
136
- },
137
- }),
138
- ).rejects.toThrow('Invalid authentication credentials')
139
-
140
- expect(spyArgonPasswordVerify).toHaveBeenCalledTimes(1)
141
- })
142
-
143
- it('should rate limit signUp attempts in production', async () => {
144
- mockCount.mockResolvedValue(1)
145
-
146
- const context = {
147
- wabe: {
148
- ...controllers,
149
- config: {
150
- isProduction: true,
151
- authentication: {
152
- security: {
153
- signUpRateLimit: {
154
- enabled: true,
155
- maxAttempts: 2,
156
- windowMs: 60_000,
157
- blockDurationMs: 60_000,
158
- },
159
- },
160
- },
161
- },
162
- },
163
- } as any
164
-
165
- const input = {
166
- phone: 'ratelimit-signup-phone-password',
167
- password: 'password',
168
- }
169
-
170
- await expect(phonePassword.onSignUp({ context, input })).rejects.toThrow(
171
- 'Not authorized to create user',
172
- )
173
- await expect(phonePassword.onSignUp({ context, input })).rejects.toThrow(
174
- 'Not authorized to create user',
175
- )
176
-
177
- const callsBeforeBlockedAttempt = mockCount.mock.calls.length
178
-
179
- await expect(phonePassword.onSignUp({ context, input })).rejects.toThrow(
180
- 'Not authorized to create user',
181
- )
182
-
183
- expect(mockCount.mock.calls.length).toBe(callsBeforeBlockedAttempt)
184
- })
185
-
186
- it('should not update authentication data if there is no user found', () => {
187
- mockGetObjects.mockResolvedValue([])
188
-
189
- spyArgonPasswordVerify.mockResolvedValueOnce(true)
190
-
191
- expect(
192
- phonePassword.onUpdateAuthenticationData?.({
193
- context: { wabe: controllers } as any,
194
- input: {
195
- phone: 'phone@test.fr',
196
- password: 'password',
197
- },
198
- userId: 'userId',
199
- }),
200
- ).rejects.toThrow('User not found')
201
- })
202
-
203
- it('should update authentication data if the userId match with an user', async () => {
204
- mockGetObject.mockResolvedValue({
205
- id: 'id',
206
- })
207
-
208
- spyBunPasswordHash.mockResolvedValueOnce('$argon2id$hashedPassword')
209
-
210
- const res = await phonePassword.onUpdateAuthenticationData?.({
211
- context: { wabe: controllers } as any,
212
- input: {
213
- phone: 'phone@test.fr',
214
- password: 'password',
215
- },
216
- userId: 'userId',
217
- })
218
-
219
- expect(res.authenticationDataToSave.phone).toBe('phone@test.fr')
220
- })
221
- })
@@ -1,136 +0,0 @@
1
- import type {
2
- AuthenticationEventsOptions,
3
- AuthenticationEventsOptionsWithUserId,
4
- ProviderInterface,
5
- } from '../interface'
6
- import { contextWithRoot, verifyArgon2 } from '../../utils/export'
7
- import type { DevWabeTypes } from '../../utils/helper'
8
- import { clearRateLimit, isRateLimited, registerRateLimitFailure } from '../security'
9
-
10
- const DUMMY_PASSWORD_HASH =
11
- '$argon2id$v=19$m=65536,t=2,p=1$wHZB9xRS/Mbo7L3SL9e935Ag5K+T2EuT/XgB8akwZgo$SPf8EZ4T1HYkuIll4v2hSzNCH7woX3VrZJo3yWg5u8U'
12
-
13
- type PhonePasswordInterface = {
14
- password: string
15
- phone: string
16
- otp?: string
17
- }
18
-
19
- export class PhonePassword implements ProviderInterface<DevWabeTypes, PhonePasswordInterface> {
20
- async onSignIn({
21
- input,
22
- context,
23
- }: AuthenticationEventsOptions<DevWabeTypes, PhonePasswordInterface>) {
24
- const normalizedPhone = input.phone.trim().toLowerCase()
25
- const rateLimitKey = `phonePassword:${normalizedPhone}`
26
-
27
- if (isRateLimited(context, 'signIn', rateLimitKey))
28
- throw new Error('Invalid authentication credentials')
29
-
30
- const users = await context.wabe.controllers.database.getObjects({
31
- className: 'User',
32
- where: {
33
- authentication: {
34
- phonePassword: {
35
- phone: { equalTo: normalizedPhone },
36
- },
37
- },
38
- },
39
- context: contextWithRoot(context),
40
- select: {
41
- authentication: true,
42
- role: true,
43
- secondFA: true,
44
- email: true,
45
- id: true,
46
- provider: true,
47
- isOauth: true,
48
- createdAt: true,
49
- updatedAt: true,
50
- },
51
- first: 1,
52
- })
53
-
54
- const user = users[0]
55
- const userDatabasePassword = user?.authentication?.phonePassword?.password
56
-
57
- const passwordHashToCheck = userDatabasePassword ?? DUMMY_PASSWORD_HASH
58
-
59
- const isPasswordEquals = await verifyArgon2(input.password, passwordHashToCheck)
60
-
61
- if (
62
- !user ||
63
- !isPasswordEquals ||
64
- normalizedPhone !== user.authentication?.phonePassword?.phone
65
- ) {
66
- registerRateLimitFailure(context, 'signIn', rateLimitKey)
67
- throw new Error('Invalid authentication credentials')
68
- }
69
-
70
- clearRateLimit(context, 'signIn', rateLimitKey)
71
-
72
- return {
73
- user,
74
- }
75
- }
76
-
77
- async onSignUp({
78
- input,
79
- context,
80
- }: AuthenticationEventsOptions<DevWabeTypes, PhonePasswordInterface>) {
81
- const normalizedPhone = input.phone.trim().toLowerCase()
82
- const rateLimitKey = `phonePassword:${normalizedPhone}`
83
-
84
- if (isRateLimited(context, 'signUp', rateLimitKey))
85
- throw new Error('Not authorized to create user')
86
-
87
- const users = await context.wabe.controllers.database.count({
88
- className: 'User',
89
- where: {
90
- authentication: {
91
- phonePassword: {
92
- phone: { equalTo: normalizedPhone },
93
- },
94
- },
95
- },
96
- context: contextWithRoot(context),
97
- })
98
-
99
- if (users > 0) {
100
- registerRateLimitFailure(context, 'signUp', rateLimitKey)
101
- throw new Error('Not authorized to create user')
102
- }
103
-
104
- clearRateLimit(context, 'signUp', rateLimitKey)
105
-
106
- return {
107
- authenticationDataToSave: {
108
- phone: normalizedPhone,
109
- password: input.password,
110
- },
111
- }
112
- }
113
-
114
- async onUpdateAuthenticationData({
115
- userId,
116
- input,
117
- context,
118
- }: AuthenticationEventsOptionsWithUserId<DevWabeTypes, PhonePasswordInterface>) {
119
- const normalizedPhone = input.phone.trim().toLowerCase()
120
- const user = await context.wabe.controllers.database.getObject({
121
- className: 'User',
122
- id: userId,
123
- context: contextWithRoot(context),
124
- select: { authentication: true },
125
- })
126
-
127
- if (!user) throw new Error('User not found')
128
-
129
- return {
130
- authenticationDataToSave: {
131
- phone: normalizedPhone ?? user?.authentication?.phonePassword?.phone,
132
- password: input.password ? input.password : user?.authentication?.phonePassword?.password,
133
- },
134
- }
135
- }
136
- }
@@ -1,77 +0,0 @@
1
- import { describe, expect, it, beforeAll, afterAll, afterEach } from 'bun:test'
2
- import type { DevWabeTypes } from '../../utils/helper'
3
- import { setupTests, closeTests } from '../../utils/testHelper'
4
- import type { Wabe } from '../..'
5
- import { OTP } from '../OTP'
6
- import { QRCodeOTP } from './QRCodeOTP'
7
-
8
- describe('QRCodeOTPProvider', () => {
9
- let wabe: Wabe<DevWabeTypes>
10
-
11
- beforeAll(async () => {
12
- const setup = await setupTests()
13
- wabe = setup.wabe
14
- })
15
-
16
- afterAll(async () => {
17
- await closeTests(wabe)
18
- })
19
-
20
- afterEach(async () => {
21
- await wabe.controllers.database.clearDatabase()
22
- })
23
-
24
- it('should return the userId if the OTP code is valid', async () => {
25
- const createdUser = await wabe.controllers.database.createObject({
26
- className: 'User',
27
- context: {
28
- wabe,
29
- isRoot: true,
30
- },
31
- data: {
32
- email: 'email@test.fr',
33
- },
34
- select: {
35
- id: true,
36
- },
37
- })
38
-
39
- if (!createdUser) throw new Error('User not created')
40
-
41
- const otp = new OTP(wabe.config.rootKey).authenticatorGenerate(createdUser.id)
42
-
43
- const qrCodeOTP = new QRCodeOTP()
44
-
45
- expect(
46
- await qrCodeOTP.onVerifyChallenge({
47
- context: {
48
- wabe,
49
- isRoot: false,
50
- },
51
- input: {
52
- email: 'email@test.fr',
53
- otp,
54
- },
55
- }),
56
- ).toEqual({
57
- userId: createdUser.id,
58
- })
59
- })
60
-
61
- it("should return null if the user doesn't exist", async () => {
62
- const qrCodeOTP = new QRCodeOTP()
63
-
64
- expect(
65
- await qrCodeOTP.onVerifyChallenge({
66
- context: {
67
- wabe,
68
- isRoot: false,
69
- },
70
- input: {
71
- email: 'email@test.fr',
72
- otp: '123456',
73
- },
74
- }),
75
- ).toEqual(null)
76
- })
77
- })
@@ -1,69 +0,0 @@
1
- import { contextWithRoot } from '../..'
2
- import type { DevWabeTypes } from '../../utils/helper'
3
- import type { OnVerifyChallengeOptions, SecondaryProviderInterface } from '../interface'
4
- import { OTP } from '../OTP'
5
- import { clearRateLimit, isRateLimited, registerRateLimitFailure } from '../security'
6
-
7
- const DUMMY_USER_ID = '00000000-0000-0000-0000-000000000000'
8
-
9
- type QRCodeOTPInterface = {
10
- email: string
11
- otp: string
12
- }
13
-
14
- export class QRCodeOTP implements SecondaryProviderInterface<DevWabeTypes, QRCodeOTPInterface> {
15
- async onSendChallenge() {
16
- // The user should check the application and get the OTP code
17
- }
18
-
19
- async onVerifyChallenge({
20
- context,
21
- input,
22
- }: OnVerifyChallengeOptions<DevWabeTypes, QRCodeOTPInterface>) {
23
- const normalizedEmail = input.email.trim().toLowerCase()
24
- const rateLimitKey = `qrCodeOtp:${normalizedEmail}`
25
-
26
- if (isRateLimited(context, 'verifyChallenge', rateLimitKey)) return null
27
-
28
- const users = await context.wabe.controllers.database.getObjects({
29
- className: 'User',
30
- where: {
31
- email: {
32
- equalTo: input.email,
33
- },
34
- },
35
- select: {
36
- authentication: true,
37
- role: true,
38
- secondFA: true,
39
- email: true,
40
- id: true,
41
- provider: true,
42
- isOauth: true,
43
- createdAt: true,
44
- updatedAt: true,
45
- },
46
- first: 1,
47
- context: contextWithRoot(context),
48
- })
49
-
50
- const realUser = users.length > 0 ? users[0] : null
51
- const userId = realUser?.id ?? DUMMY_USER_ID
52
-
53
- const isDevBypass =
54
- !context.wabe.config.isProduction && input.otp === '000000' && realUser !== null
55
-
56
- const otpClass = new OTP(context.wabe.config.rootKey)
57
-
58
- const isOtpValid = otpClass.authenticatorVerify(input.otp, userId)
59
-
60
- if (realUser && (isOtpValid || isDevBypass)) {
61
- clearRateLimit(context, 'verifyChallenge', rateLimitKey)
62
- return { userId: realUser.id }
63
- }
64
-
65
- registerRateLimitFailure(context, 'verifyChallenge', rateLimitKey)
66
-
67
- return null
68
- }
69
- }
@@ -1,6 +0,0 @@
1
- export * from './EmailPassword'
2
- export * from './Google'
3
- export * from './GitHub'
4
- export * from './PhonePassword'
5
- export * from './EmailOTP'
6
- export * from './QRCodeOTP'
@@ -1,30 +0,0 @@
1
- import { describe, expect, it, spyOn } from 'bun:test'
2
- import { refreshResolver } from './refreshResolver'
3
- import type { WabeContext } from '../../server/interface'
4
- import { Session } from '../Session'
5
-
6
- const context: WabeContext<any> = {
7
- sessionId: 'sessionId',
8
- user: {} as any,
9
- isRoot: false,
10
- } as WabeContext<any>
11
-
12
- describe('refreshResolver', () => {
13
- it('should refresh the session', async () => {
14
- const spyRefreshSession = spyOn(Session.prototype, 'refresh').mockResolvedValue({} as any)
15
-
16
- await refreshResolver(
17
- null,
18
- {
19
- input: {
20
- accessToken: 'accessToken',
21
- refreshToken: 'refreshToken',
22
- },
23
- },
24
- context,
25
- )
26
-
27
- expect(spyRefreshSession).toHaveBeenCalledTimes(1)
28
- expect(spyRefreshSession).toHaveBeenCalledWith('accessToken', 'refreshToken', context)
29
- })
30
- })
@@ -1,19 +0,0 @@
1
- import type { WabeContext } from '../../server/interface'
2
- import type { DevWabeTypes } from '../../utils/helper'
3
- import { Session } from '../Session'
4
-
5
- export const refreshResolver = async (_: any, args: any, context: WabeContext<DevWabeTypes>) => {
6
- const {
7
- input: { refreshToken, accessToken },
8
- } = args
9
-
10
- const session = new Session<DevWabeTypes>()
11
-
12
- const { accessToken: newAccessToken, refreshToken: newRefreshToken } = await session.refresh(
13
- accessToken,
14
- refreshToken,
15
- context,
16
- )
17
-
18
- return { accessToken: newAccessToken, refreshToken: newRefreshToken }
19
- }
@@ -1,59 +0,0 @@
1
- import { describe, it, beforeAll, afterAll, expect } from 'bun:test'
2
- import { gql } from 'graphql-request'
3
- import type { Wabe } from 'src'
4
- import { getAdminUserClient, type DevWabeTypes } from 'src/utils/helper'
5
- import { setupTests, closeTests } from 'src/utils/testHelper'
6
-
7
- describe('signInWithResolver integration test', () => {
8
- let wabe: Wabe<DevWabeTypes>
9
-
10
- beforeAll(async () => {
11
- const setup = await setupTests()
12
- wabe = setup.wabe
13
- })
14
-
15
- afterAll(async () => {
16
- await closeTests(wabe)
17
- })
18
-
19
- it('should return all fields of the user on signInWith resolver', async () => {
20
- const adminClient = await getAdminUserClient(wabe.config.port, wabe, {
21
- email: 'admin@wabe.dev',
22
- password: 'admin',
23
- })
24
- const res = await adminClient.request<any>(
25
- gql`
26
- mutation signInWith($input: SignInWithInput!) {
27
- signInWith(input: $input) {
28
- user {
29
- id
30
- authentication {
31
- emailPassword {
32
- email
33
- }
34
- }
35
- role {
36
- name
37
- }
38
- }
39
- }
40
- }
41
- `,
42
- {
43
- input: {
44
- authentication: {
45
- emailPassword: {
46
- email: 'admin@wabe.dev',
47
- password: 'admin',
48
- },
49
- },
50
- },
51
- },
52
- )
53
-
54
- expect(res.signInWith.user.role.name).toBe('Admin')
55
- expect(res.signInWith.user.authentication.emailPassword).toEqual({
56
- email: 'admin@wabe.dev',
57
- })
58
- })
59
- })