@volcanicminds/backend 2.3.1 → 3.0.0

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 (173) hide show
  1. package/README.md +240 -28
  2. package/dist/index.d.ts +3 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +24 -36
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/api/auth/controller/auth.d.ts.map +1 -1
  7. package/dist/lib/api/auth/controller/auth.js +14 -7
  8. package/dist/lib/api/auth/controller/auth.js.map +1 -1
  9. package/dist/lib/api/health/controller/health.d.ts +1 -1
  10. package/dist/lib/api/health/controller/health.d.ts.map +1 -1
  11. package/dist/lib/api/health/controller/health.js +1 -1
  12. package/dist/lib/api/health/controller/health.js.map +1 -1
  13. package/dist/lib/api/health/routes.d.ts +1 -0
  14. package/dist/lib/api/health/routes.d.ts.map +1 -1
  15. package/dist/lib/api/health/routes.js +1 -0
  16. package/dist/lib/api/health/routes.js.map +1 -1
  17. package/dist/lib/api/tenants/controller/tenants.d.ts +17 -0
  18. package/dist/lib/api/tenants/controller/tenants.d.ts.map +1 -0
  19. package/dist/lib/api/tenants/controller/tenants.js +150 -0
  20. package/dist/lib/api/tenants/controller/tenants.js.map +1 -0
  21. package/dist/lib/api/tenants/routes.d.ts +167 -0
  22. package/dist/lib/api/tenants/routes.d.ts.map +1 -0
  23. package/dist/lib/api/tenants/routes.js +143 -0
  24. package/dist/lib/api/tenants/routes.js.map +1 -0
  25. package/dist/lib/config/plugins.js +1 -1
  26. package/dist/lib/config/plugins.js.map +1 -1
  27. package/dist/lib/database/typeorm/entities/change.d.ts +11 -0
  28. package/dist/lib/database/typeorm/entities/change.d.ts.map +1 -0
  29. package/dist/lib/database/typeorm/entities/change.js +4 -0
  30. package/dist/lib/database/typeorm/entities/change.js.map +1 -0
  31. package/dist/lib/database/typeorm/entities/tenant.d.ts +13 -0
  32. package/dist/lib/database/typeorm/entities/tenant.d.ts.map +1 -0
  33. package/dist/lib/database/typeorm/entities/tenant.js +4 -0
  34. package/dist/lib/database/typeorm/entities/tenant.js.map +1 -0
  35. package/dist/lib/database/typeorm/entities/token.d.ts +16 -0
  36. package/dist/lib/database/typeorm/entities/token.d.ts.map +1 -0
  37. package/dist/lib/database/typeorm/entities/token.js +4 -0
  38. package/dist/lib/database/typeorm/entities/token.js.map +1 -0
  39. package/dist/lib/database/typeorm/entities/user.d.ts +28 -0
  40. package/dist/lib/database/typeorm/entities/user.d.ts.map +1 -0
  41. package/dist/lib/database/typeorm/entities/user.js +4 -0
  42. package/dist/lib/database/typeorm/entities/user.js.map +1 -0
  43. package/dist/lib/database/typeorm/loader/dataBaseManager.d.ts +6 -0
  44. package/dist/lib/database/typeorm/loader/dataBaseManager.d.ts.map +1 -0
  45. package/dist/lib/database/typeorm/loader/dataBaseManager.js +73 -0
  46. package/dist/lib/database/typeorm/loader/dataBaseManager.js.map +1 -0
  47. package/dist/lib/database/typeorm/loader/entities.d.ts +6 -0
  48. package/dist/lib/database/typeorm/loader/entities.d.ts.map +1 -0
  49. package/dist/lib/database/typeorm/loader/entities.js +37 -0
  50. package/dist/lib/database/typeorm/loader/entities.js.map +1 -0
  51. package/dist/lib/database/typeorm/loader/tenantManager.d.ts +17 -0
  52. package/dist/lib/database/typeorm/loader/tenantManager.d.ts.map +1 -0
  53. package/dist/lib/database/typeorm/loader/tenantManager.js +193 -0
  54. package/dist/lib/database/typeorm/loader/tenantManager.js.map +1 -0
  55. package/dist/lib/database/typeorm/loader/tokenManager.d.ts +23 -0
  56. package/dist/lib/database/typeorm/loader/tokenManager.d.ts.map +1 -0
  57. package/dist/lib/database/typeorm/loader/tokenManager.js +131 -0
  58. package/dist/lib/database/typeorm/loader/tokenManager.js.map +1 -0
  59. package/dist/lib/database/typeorm/loader/userManager.d.ts +39 -0
  60. package/dist/lib/database/typeorm/loader/userManager.d.ts.map +1 -0
  61. package/dist/lib/database/typeorm/loader/userManager.js +358 -0
  62. package/dist/lib/database/typeorm/loader/userManager.js.map +1 -0
  63. package/dist/lib/database/typeorm/query/builder.d.ts +2 -0
  64. package/dist/lib/database/typeorm/query/builder.d.ts.map +1 -0
  65. package/dist/lib/database/typeorm/query/builder.js +33 -0
  66. package/dist/lib/database/typeorm/query/builder.js.map +1 -0
  67. package/dist/lib/database/typeorm/query/parser.d.ts +2 -0
  68. package/dist/lib/database/typeorm/query/parser.d.ts.map +1 -0
  69. package/dist/lib/database/typeorm/query/parser.js +27 -0
  70. package/dist/lib/database/typeorm/query/parser.js.map +1 -0
  71. package/dist/lib/database/typeorm/query.d.ts +36 -0
  72. package/dist/lib/database/typeorm/query.d.ts.map +1 -0
  73. package/dist/lib/database/typeorm/query.js +259 -0
  74. package/dist/lib/database/typeorm/query.js.map +1 -0
  75. package/dist/lib/database/typeorm/util/crypto.d.ts +3 -0
  76. package/dist/lib/database/typeorm/util/crypto.d.ts.map +1 -0
  77. package/dist/lib/database/typeorm/util/crypto.js +46 -0
  78. package/dist/lib/database/typeorm/util/crypto.js.map +1 -0
  79. package/dist/lib/database/typeorm/util/error.d.ts +5 -0
  80. package/dist/lib/database/typeorm/util/error.d.ts.map +1 -0
  81. package/dist/lib/database/typeorm/util/error.js +8 -0
  82. package/dist/lib/database/typeorm/util/error.js.map +1 -0
  83. package/dist/lib/database/typeorm/util/logger.d.ts +7 -0
  84. package/dist/lib/database/typeorm/util/logger.d.ts.map +1 -0
  85. package/dist/lib/database/typeorm/util/logger.js +31 -0
  86. package/dist/lib/database/typeorm/util/logger.js.map +1 -0
  87. package/dist/lib/database/typeorm/util/yn.d.ts +2 -0
  88. package/dist/lib/database/typeorm/util/yn.d.ts.map +1 -0
  89. package/dist/lib/database/typeorm/util/yn.js +15 -0
  90. package/dist/lib/database/typeorm/util/yn.js.map +1 -0
  91. package/dist/lib/defaults/managers.d.ts.map +1 -1
  92. package/dist/lib/defaults/managers.js +186 -58
  93. package/dist/lib/defaults/managers.js.map +1 -1
  94. package/dist/lib/hooks/onRequest.d.ts.map +1 -1
  95. package/dist/lib/hooks/onRequest.js +11 -48
  96. package/dist/lib/hooks/onRequest.js.map +1 -1
  97. package/dist/lib/loader/router.d.ts.map +1 -1
  98. package/dist/lib/loader/router.js +92 -83
  99. package/dist/lib/loader/router.js.map +1 -1
  100. package/dist/lib/loader/tenant.d.ts.map +1 -1
  101. package/dist/lib/loader/tenant.js +25 -2
  102. package/dist/lib/loader/tenant.js.map +1 -1
  103. package/dist/lib/locales/en.json +12 -0
  104. package/dist/lib/locales/it.json +12 -0
  105. package/dist/lib/schemas/tenant.d.ts +88 -0
  106. package/dist/lib/schemas/tenant.d.ts.map +1 -0
  107. package/dist/lib/schemas/tenant.js +45 -0
  108. package/dist/lib/schemas/tenant.js.map +1 -0
  109. package/dist/lib/util/regexp.d.ts +2 -0
  110. package/dist/lib/util/regexp.d.ts.map +1 -1
  111. package/dist/lib/util/regexp.js +5 -3
  112. package/dist/lib/util/regexp.js.map +1 -1
  113. package/dist/lib/util/secret.d.ts +11 -0
  114. package/dist/lib/util/secret.d.ts.map +1 -0
  115. package/dist/lib/util/secret.js +70 -0
  116. package/dist/lib/util/secret.js.map +1 -0
  117. package/dist/server.js +4 -1
  118. package/dist/server.js.map +1 -1
  119. package/dist/typeorm.d.ts +15 -0
  120. package/dist/typeorm.d.ts.map +1 -0
  121. package/dist/typeorm.js +86 -0
  122. package/dist/typeorm.js.map +1 -0
  123. package/dist/types/database/typeorm/global.d.ts +56 -0
  124. package/dist/types/database/typeorm/global.d.ts.map +1 -0
  125. package/dist/types/database/typeorm/global.js +2 -0
  126. package/dist/types/database/typeorm/global.js.map +1 -0
  127. package/dist/types/global.d.ts +318 -0
  128. package/dist/types/orm.d.ts +22 -0
  129. package/lib/api/auth/controller/auth.ts +28 -12
  130. package/lib/api/health/controller/health.ts +1 -1
  131. package/lib/api/health/routes.ts +1 -0
  132. package/lib/api/tenants/controller/tenants.ts +211 -0
  133. package/lib/api/tenants/routes.ts +145 -0
  134. package/lib/config/plugins.ts +1 -1
  135. package/lib/database/typeorm/entities/change.ts +11 -0
  136. package/lib/database/typeorm/entities/tenant.ts +20 -0
  137. package/lib/database/typeorm/entities/token.ts +18 -0
  138. package/lib/database/typeorm/entities/user.ts +33 -0
  139. package/lib/database/typeorm/loader/dataBaseManager.ts +89 -0
  140. package/lib/database/typeorm/loader/entities.ts +47 -0
  141. package/lib/database/typeorm/loader/tenantManager.ts +260 -0
  142. package/lib/database/typeorm/loader/tokenManager.ts +157 -0
  143. package/lib/database/typeorm/loader/userManager.ts +432 -0
  144. package/lib/database/typeorm/query/builder.ts +39 -0
  145. package/lib/database/typeorm/query/parser.ts +29 -0
  146. package/lib/database/typeorm/query.ts +326 -0
  147. package/lib/database/typeorm/util/crypto.ts +52 -0
  148. package/lib/database/typeorm/util/error.ts +7 -0
  149. package/lib/database/typeorm/util/logger.ts +35 -0
  150. package/lib/database/typeorm/util/yn.ts +20 -0
  151. package/lib/defaults/managers.ts +191 -64
  152. package/lib/hooks/onRequest.ts +12 -64
  153. package/lib/loader/router.ts +133 -110
  154. package/lib/loader/tenant.ts +37 -14
  155. package/lib/schemas/tenant.ts +49 -0
  156. package/lib/util/regexp.ts +31 -8
  157. package/lib/util/secret.ts +113 -0
  158. package/package.json +54 -13
  159. package/dist/lib/apollo/context.d.ts +0 -6
  160. package/dist/lib/apollo/context.d.ts.map +0 -1
  161. package/dist/lib/apollo/context.js +0 -5
  162. package/dist/lib/apollo/context.js.map +0 -1
  163. package/dist/lib/apollo/resolvers.d.ts +0 -8
  164. package/dist/lib/apollo/resolvers.d.ts.map +0 -1
  165. package/dist/lib/apollo/resolvers.js +0 -8
  166. package/dist/lib/apollo/resolvers.js.map +0 -1
  167. package/dist/lib/apollo/type-defs.d.ts +0 -3
  168. package/dist/lib/apollo/type-defs.d.ts.map +0 -1
  169. package/dist/lib/apollo/type-defs.js +0 -8
  170. package/dist/lib/apollo/type-defs.js.map +0 -1
  171. package/lib/apollo/context.ts +0 -11
  172. package/lib/apollo/resolvers.ts +0 -12
  173. package/lib/apollo/type-defs.ts +0 -9
@@ -1,9 +1,8 @@
1
-
2
- import {
3
- UserManagement,
4
- TokenManagement,
5
- DataBaseManagement,
6
- MfaManagement,
1
+ import {
2
+ UserManagement,
3
+ TokenManagement,
4
+ DataBaseManagement,
5
+ MfaManagement,
7
6
  TransferManagement,
8
7
  TenantManagement,
9
8
  TransferCallback
@@ -12,77 +11,205 @@ import { FastifyReply, FastifyRequest } from 'fastify'
12
11
 
13
12
  // Default implementations that throw errors or return not implemented
14
13
  export const defaultTenantManager: TenantManagement = {
15
- isImplemented() { return false },
16
- resolveTenant(_req) { throw new Error('Not implemented') },
17
- switchContext(_tenant, _db?) { throw new Error('Not implemented') },
18
- createTenant(_data) { throw new Error('Not implemented') },
19
- deleteTenant(_id) { throw new Error('Not implemented') }
14
+ isImplemented() {
15
+ return false
16
+ },
17
+ resolveTenant(_req) {
18
+ throw new Error('Not implemented')
19
+ },
20
+ switchContext(_tenant, _db?) {
21
+ throw new Error('Not implemented')
22
+ },
23
+ createTenant(_data) {
24
+ throw new Error('Not implemented')
25
+ },
26
+ deleteTenant(_id) {
27
+ throw new Error('Not implemented')
28
+ },
29
+ listTenants() {
30
+ throw new Error('Not implemented')
31
+ },
32
+ getTenant(_id) {
33
+ throw new Error('Not implemented')
34
+ },
35
+ updateTenant(_id, _data) {
36
+ throw new Error('Not implemented')
37
+ },
38
+ restoreTenant(_id) {
39
+ throw new Error('Not implemented')
40
+ }
20
41
  }
21
42
 
22
43
  export const defaultUserManager: UserManagement = {
23
- isImplemented() { return false },
24
- isValidUser(_data: unknown) { throw new Error('Not implemented.') },
25
- createUser(_data: unknown) { throw new Error('Not implemented.') },
26
- deleteUser(_data: unknown) { throw new Error('Not implemented.') },
27
- resetExternalId(_data: unknown) { throw new Error('Not implemented.') },
28
- updateUserById(_id: string, _user: unknown) { throw new Error('Not implemented.') },
29
- retrieveUserById(_id: string) { throw new Error('Not implemented.') },
30
- retrieveUserByEmail(_email: string) { throw new Error('Not implemented.') },
31
- retrieveUserByConfirmationToken(_code: string) { throw new Error('Not implemented.') },
32
- retrieveUserByResetPasswordToken(_code: string) { throw new Error('Not implemented.') },
33
- retrieveUserByUsername(_username: string) { throw new Error('Not implemented.') },
34
- retrieveUserByExternalId(_externalId: string) { throw new Error('Not implemented.') },
35
- retrieveUserByPassword(_email: string, _password: string) { throw new Error('Not implemented.') },
36
- changePassword(_email: string, _password: string, _oldPassword: string) { throw new Error('Not implemented.') },
37
- forgotPassword(_email: string) { throw new Error('Not implemented.') },
38
- userConfirmation(_user: unknown) { throw new Error('Not implemented.') },
39
- resetPassword(_user: unknown, _password: string) { throw new Error('Not implemented.') },
40
- blockUserById(_id: string, _reason: string) { throw new Error('Not implemented.') },
41
- unblockUserById(_data: unknown) { throw new Error('Not implemented.') },
42
- countQuery(_data: unknown) { throw new Error('Not implemented.') },
43
- findQuery(_data: unknown) { throw new Error('Not implemented.') },
44
- disableUserById(_id: string) { throw new Error('Not implemented.') },
45
- saveMfaSecret(_userId: string, _secret: string) { throw new Error('Not implemented.') },
46
- retrieveMfaSecret(_userId: string) { throw new Error('Not implemented.') },
47
- enableMfa(_userId: string) { throw new Error('Not implemented.') },
48
- disableMfa(_userId: string) { throw new Error('Not implemented.') },
49
- forceDisableMfaForAdmin(_email: string) { throw new Error('Not implemented.') }
44
+ isImplemented() {
45
+ return false
46
+ },
47
+ isValidUser(_data: unknown) {
48
+ throw new Error('Not implemented.')
49
+ },
50
+ createUser(_data: unknown) {
51
+ throw new Error('Not implemented.')
52
+ },
53
+ deleteUser(_data: unknown) {
54
+ throw new Error('Not implemented.')
55
+ },
56
+ resetExternalId(_data: unknown) {
57
+ throw new Error('Not implemented.')
58
+ },
59
+ updateUserById(_id: string, _user: unknown) {
60
+ throw new Error('Not implemented.')
61
+ },
62
+ retrieveUserById(_id: string) {
63
+ throw new Error('Not implemented.')
64
+ },
65
+ retrieveUserByEmail(_email: string) {
66
+ throw new Error('Not implemented.')
67
+ },
68
+ retrieveUserByConfirmationToken(_code: string) {
69
+ throw new Error('Not implemented.')
70
+ },
71
+ retrieveUserByResetPasswordToken(_code: string) {
72
+ throw new Error('Not implemented.')
73
+ },
74
+ retrieveUserByUsername(_username: string) {
75
+ throw new Error('Not implemented.')
76
+ },
77
+ retrieveUserByExternalId(_externalId: string) {
78
+ throw new Error('Not implemented.')
79
+ },
80
+ retrieveUserByPassword(_email: string, _password: string) {
81
+ throw new Error('Not implemented.')
82
+ },
83
+ changePassword(_email: string, _password: string, _oldPassword: string) {
84
+ throw new Error('Not implemented.')
85
+ },
86
+ forgotPassword(_email: string) {
87
+ throw new Error('Not implemented.')
88
+ },
89
+ userConfirmation(_user: unknown) {
90
+ throw new Error('Not implemented.')
91
+ },
92
+ resetPassword(_user: unknown, _password: string) {
93
+ throw new Error('Not implemented.')
94
+ },
95
+ blockUserById(_id: string, _reason: string) {
96
+ throw new Error('Not implemented.')
97
+ },
98
+ unblockUserById(_data: unknown) {
99
+ throw new Error('Not implemented.')
100
+ },
101
+ countQuery(_data: unknown) {
102
+ throw new Error('Not implemented.')
103
+ },
104
+ findQuery(_data: unknown) {
105
+ throw new Error('Not implemented.')
106
+ },
107
+ disableUserById(_id: string) {
108
+ throw new Error('Not implemented.')
109
+ },
110
+ saveMfaSecret(_userId: string, _secret: string) {
111
+ throw new Error('Not implemented.')
112
+ },
113
+ retrieveMfaSecret(_userId: string) {
114
+ throw new Error('Not implemented.')
115
+ },
116
+ enableMfa(_userId: string) {
117
+ throw new Error('Not implemented.')
118
+ },
119
+ disableMfa(_userId: string) {
120
+ throw new Error('Not implemented.')
121
+ },
122
+ forceDisableMfaForAdmin(_email: string) {
123
+ throw new Error('Not implemented.')
124
+ }
50
125
  }
51
126
 
52
127
  export const defaultTokenManager: TokenManagement = {
53
- isImplemented() { return false },
54
- isValidToken(_data: unknown) { throw new Error('Not implemented.') },
55
- createToken(_data: unknown) { throw new Error('Not implemented.') },
56
- resetExternalId(_id: string) { throw new Error('Not implemented.') },
57
- updateTokenById(_id: string, _token: unknown) { throw new Error('Not implemented.') },
58
- retrieveTokenById(_id: string) { throw new Error('Not implemented.') },
59
- retrieveTokenByExternalId(_id: string) { throw new Error('Not implemented.') },
60
- blockTokenById(_id: string, _reason: string) { throw new Error('Not implemented.') },
61
- unblockTokenById(_id: string) { throw new Error('Not implemented.') },
62
- countQuery(_data: unknown) { throw new Error('Not implemented.') },
63
- findQuery(_data: unknown) { throw new Error('Not implemented.') },
64
- removeTokenById(_id: string) { throw new Error('Not implemented.') }
128
+ isImplemented() {
129
+ return false
130
+ },
131
+ isValidToken(_data: unknown) {
132
+ throw new Error('Not implemented.')
133
+ },
134
+ createToken(_data: unknown) {
135
+ throw new Error('Not implemented.')
136
+ },
137
+ resetExternalId(_id: string) {
138
+ throw new Error('Not implemented.')
139
+ },
140
+ updateTokenById(_id: string, _token: unknown) {
141
+ throw new Error('Not implemented.')
142
+ },
143
+ retrieveTokenById(_id: string) {
144
+ throw new Error('Not implemented.')
145
+ },
146
+ retrieveTokenByExternalId(_id: string) {
147
+ throw new Error('Not implemented.')
148
+ },
149
+ blockTokenById(_id: string, _reason: string) {
150
+ throw new Error('Not implemented.')
151
+ },
152
+ unblockTokenById(_id: string) {
153
+ throw new Error('Not implemented.')
154
+ },
155
+ countQuery(_data: unknown) {
156
+ throw new Error('Not implemented.')
157
+ },
158
+ findQuery(_data: unknown) {
159
+ throw new Error('Not implemented.')
160
+ },
161
+ removeTokenById(_id: string) {
162
+ throw new Error('Not implemented.')
163
+ }
65
164
  }
66
165
 
67
166
  export const defaultDataBaseManager: DataBaseManagement = {
68
- isImplemented() { return false },
69
- synchronizeSchemas() { throw new Error('Not implemented.') },
70
- retrieveBy(_entityName, _entityId) { throw new Error('Not implemented.') },
71
- addChange(_entityName, _entityId, _status, _userId, _contents, _changeEntity) { throw new Error('Not implemented.') }
167
+ isImplemented() {
168
+ return false
169
+ },
170
+ synchronizeSchemas() {
171
+ throw new Error('Not implemented.')
172
+ },
173
+ retrieveBy(_entityName, _entityId) {
174
+ throw new Error('Not implemented.')
175
+ },
176
+ addChange(_entityName, _entityId, _status, _userId, _contents, _changeEntity) {
177
+ throw new Error('Not implemented.')
178
+ }
72
179
  }
73
180
 
74
181
  export const defaultMfaManager: MfaManagement = {
75
- generateSetup(_appName: string, _email: string) { throw new Error('Not implemented.') },
76
- verify(_token: string, _secret: string) { throw new Error('Not implemented.') }
182
+ generateSetup(_appName: string, _email: string) {
183
+ throw new Error('Not implemented.')
184
+ },
185
+ verify(_token: string, _secret: string) {
186
+ throw new Error('Not implemented.')
187
+ }
77
188
  }
78
189
 
79
190
  export const defaultTransferManager: TransferManagement = {
80
- isImplemented() { return false },
81
- getPath() { throw new Error('Not implemented.') },
82
- getServer() { throw new Error('Not implemented.') },
83
- onUploadCreate(_callback: TransferCallback) { throw new Error('Not implemented.') },
84
- onUploadFinish(_callback: TransferCallback) { throw new Error('Not implemented.') },
85
- onUploadTerminate(_callback: TransferCallback) { throw new Error('Not implemented.') },
86
- handle(_req: FastifyRequest, _res: FastifyReply) { throw new Error('Not implemented.') },
87
- isValid(_req: FastifyRequest) { throw new Error('Not implemented.') }
191
+ isImplemented() {
192
+ return false
193
+ },
194
+ getPath() {
195
+ throw new Error('Not implemented.')
196
+ },
197
+ getServer() {
198
+ throw new Error('Not implemented.')
199
+ },
200
+ onUploadCreate(_callback: TransferCallback) {
201
+ throw new Error('Not implemented.')
202
+ },
203
+ onUploadFinish(_callback: TransferCallback) {
204
+ throw new Error('Not implemented.')
205
+ },
206
+ onUploadTerminate(_callback: TransferCallback) {
207
+ throw new Error('Not implemented.')
208
+ },
209
+ handle(_req: FastifyRequest, _res: FastifyReply) {
210
+ throw new Error('Not implemented.')
211
+ },
212
+ isValid(_req: FastifyRequest) {
213
+ throw new Error('Not implemented.')
214
+ }
88
215
  }
@@ -2,8 +2,6 @@
2
2
  import { getParams, getData } from '../util/common.js'
3
3
  import type { AuthenticatedUser, AuthenticatedToken, Role, TransferManagement } from '../../types/global.js'
4
4
 
5
- const { embedded_auth = true } = global.config?.options || {}
6
-
7
5
  const MFA_SETUP_WHITELIST = ['/auth/mfa/setup', '/auth/mfa/enable', '/auth/mfa/verify', '/auth/logout']
8
6
 
9
7
  const normalizeRoles = (rolesArray: any[] | undefined): string[] => {
@@ -23,63 +21,6 @@ const normalizeRoles = (rolesArray: any[] | undefined): string[] => {
23
21
  export default async (req, reply) => {
24
22
  if (log.i) req.startedAt = new Date()
25
23
 
26
- const { multi_tenant } = global.config?.options || {}
27
-
28
- if (multi_tenant?.enabled) {
29
- let tenantSlug: string | undefined
30
-
31
- if (multi_tenant.resolver === 'subdomain') {
32
- const host = req.headers.host || ''
33
- const parts = host.split('.')
34
- if (parts.length >= 2) {
35
- // FIXME: Improve subdomain extraction strategy. Currently assumes [slug].[domain].[tld] or [slug].localhost
36
- if (parts[0] !== 'www') {
37
- tenantSlug = parts[0]
38
- }
39
- }
40
- } else if (multi_tenant.resolver === 'header') {
41
- tenantSlug = req.headers[multi_tenant?.header_key || 'x-tenant-id'] as string
42
- } else if (multi_tenant.resolver === 'query') {
43
- tenantSlug = (req.query as any)[multi_tenant?.query_key || 'tid']
44
- }
45
-
46
- if (!tenantSlug) {
47
- return reply.code(400).send({ statusCode: 400, error: 'Tenant ID missing', message: 'Tenant ID is required' })
48
- }
49
-
50
- if (!global.repository?.tenants) {
51
- log.error('Multi-tenant enabled but global.repository.tenants not found')
52
- return reply.code(500).send({ statusCode: 500, error: 'Internal Server Error' })
53
- }
54
-
55
- const tenant = await global.repository.tenants.findOneBy({ slug: tenantSlug })
56
-
57
- if (!tenant) {
58
- return reply
59
- .code(404)
60
- .send({ statusCode: 404, error: 'Tenant Not Found', message: `Tenant '${tenantSlug}' not found` })
61
- }
62
-
63
- if (tenant.status !== 'active') {
64
- return reply.code(403).send({ statusCode: 403, error: 'Tenant Inactive', message: 'Tenant is not active' })
65
- }
66
-
67
- // Tenant Context Setup
68
- const runner = global.connection.createQueryRunner()
69
- await runner.connect()
70
-
71
- // Validate schema name safety
72
- if (!/^[a-z0-9_]+$/i.test(tenant.schema)) {
73
- await runner.release()
74
- return reply.code(400).send({ statusCode: 400, error: 'Invalid Schema Name' })
75
- }
76
-
77
- await runner.query(`SET search_path TO "${tenant.schema}", "public"`)
78
-
79
- req.runner = runner
80
- req.tenant = tenant
81
- }
82
-
83
24
  req.data = () => getData(req)
84
25
  req.parameters = () => getParams(req)
85
26
 
@@ -102,6 +43,8 @@ export default async (req, reply) => {
102
43
  }
103
44
  }
104
45
 
46
+ const { embedded_auth = true } = global.config?.options || {}
47
+
105
48
  if (embedded_auth) {
106
49
  req.roles = () => [roles.public.code]
107
50
  req.hasRole = (r: Role) => req.roles().includes(r?.code)
@@ -133,7 +76,14 @@ export default async (req, reply) => {
133
76
 
134
77
  // Validate Tenant Access
135
78
  const { multi_tenant } = global.config?.options || {}
136
- if (multi_tenant?.enabled && req.tenant && tokenData.tid) {
79
+ if (multi_tenant?.enabled && cfg.tenantContext !== false) {
80
+ if (!req.tenant || !tokenData.tid) {
81
+ return reply.status(403).send({
82
+ statusCode: 403,
83
+ code: 'TENANT_NOT_FOUND',
84
+ message: 'Token does not belong to this tenant'
85
+ })
86
+ }
137
87
  if (tokenData.tid !== req.tenant.id) {
138
88
  return reply.status(403).send({
139
89
  statusCode: 403,
@@ -168,7 +118,7 @@ export default async (req, reply) => {
168
118
  let token: null | AuthenticatedToken = null
169
119
 
170
120
  if (req.server['userManager']?.isImplemented()) {
171
- user = await req.server['userManager'].retrieveUserByExternalId(subjectId)
121
+ user = await req.server['userManager'].retrieveUserByExternalId(subjectId, req.db)
172
122
  if (user) {
173
123
  const isValid = await req.server['userManager'].isValidUser(user)
174
124
  if (!isValid) {
@@ -181,7 +131,7 @@ export default async (req, reply) => {
181
131
  }
182
132
 
183
133
  if (!user && req.server['tokenManager']?.isImplemented()) {
184
- token = await req.server['tokenManager'].retrieveTokenByExternalId(subjectId)
134
+ token = await req.server['tokenManager'].retrieveTokenByExternalId(subjectId, req.db)
185
135
  if (token) {
186
136
  const isValid = await req.server['tokenManager'].isValidToken(token)
187
137
  if (!isValid) {
@@ -223,5 +173,3 @@ export default async (req, reply) => {
223
173
  }
224
174
  }
225
175
  }
226
-
227
-
@@ -61,6 +61,132 @@ async function loadMiddlewares(base: string, middlewares: string[] = []) {
61
61
  return midds
62
62
  }
63
63
 
64
+
65
+ function processRoute(
66
+ route: Route,
67
+ index: number,
68
+ file: string,
69
+ dir: string,
70
+ base: string,
71
+ defaultConfig: any,
72
+ authMiddlewares: string[],
73
+ validRoutes: ConfiguredRoute[]
74
+ ): ConfiguredRoute | null {
75
+ const errors: string[] = []
76
+ const {
77
+ method: methodCase,
78
+ path: pathName = '/',
79
+ handler,
80
+ roles: rs = [],
81
+ config = {} as RouteConfig,
82
+ middlewares = [],
83
+ rateLimit
84
+ } = route
85
+
86
+ const rsp = !rs.length ? [roles.public] : rs
87
+ let requiredRoles: Role[] = []
88
+
89
+ try {
90
+ requiredRoles = rsp.some((r) => r.code === roles.admin.code) ? rsp : [...rsp, roles.admin]
91
+ } catch (err) {
92
+ if (log.e) log.error(`Error in loading roles for ${methodCase} ${pathName} (${handler})`)
93
+ if (log.t) log.trace(err)
94
+ config.enable = false
95
+ }
96
+
97
+ const reqAuth: boolean =
98
+ middlewares.some((m) => authMiddlewares.includes(m)) ||
99
+ requiredRoles.every((r) => r.code !== roles.public.code)
100
+
101
+ if (!config?.security && reqAuth) {
102
+ config.security = 'bearer'
103
+ }
104
+
105
+ const {
106
+ title = '',
107
+ description = '',
108
+ enable = yn(defaultConfig.enable, true),
109
+ deprecated = yn(defaultConfig.deprecated, false),
110
+ tenantContext = yn(defaultConfig.tenantContext, true),
111
+ tags = defaultConfig.tags,
112
+ version = defaultConfig.version || '',
113
+ security = defaultConfig.security,
114
+ query,
115
+ params,
116
+ body,
117
+ response,
118
+ consumes,
119
+ rawBody = false
120
+ } = config || {}
121
+
122
+ const endpoint = `${dir}${pathName.replace(/\/+$/, '')}`
123
+ const method = methodCase.toUpperCase()
124
+ const num = index + 1
125
+ const handlerParts = handler.split('.')
126
+
127
+ if (enable) {
128
+ if (!pathName.startsWith('/')) errors.push(`Error in [${file}] bad path [${pathName}] at route n. ${num}`)
129
+ if (!methods.includes(method)) errors.push(`Error in [${file}] bad method [${method}] at route n. ${num}`)
130
+ if (handlerParts.length !== 2) errors.push(`Error in [${file}] bad handler [${handler}] at route n. ${num}`)
131
+
132
+ const key = method + endpoint + version
133
+ if (validRoutes.some((r) => `${r.method}${r.path}${r.doc?.version}` === key)) {
134
+ errors.push(`Error in [${file}] duplicated path [${pathName}] at route n. ${num}`)
135
+ }
136
+
137
+ if (errors.length > 0) {
138
+ if (log.e) errors.forEach((error) => log.error(error))
139
+ }
140
+ }
141
+
142
+ const toAdd = enable && errors.length === 0
143
+ if (toAdd) {
144
+ if (log.t)
145
+ log.trace(
146
+ `* Method [${method}] path ${endpoint} handler ${handler} enabled with ${
147
+ middlewares?.length || 0
148
+ } middlewares`
149
+ )
150
+ } else {
151
+ if (log.w) log.warn(`* Method [${method}] path ${endpoint} handler ${handler} disabled. Skip.`)
152
+ }
153
+
154
+ if (toAdd) {
155
+ const doc = {
156
+ summary: title,
157
+ description,
158
+ deprecated,
159
+ tags,
160
+ version,
161
+ security: security === 'bearer' ? [{ Bearer: [] }] : security,
162
+ response
163
+ } as any
164
+
165
+ if (query) doc.querystring = query
166
+ if (params) doc.params = params
167
+ if (body) doc.body = body
168
+ if (consumes) doc.consumes = consumes
169
+
170
+ return {
171
+ handler,
172
+ method,
173
+ path: '/' + endpoint,
174
+ middlewares,
175
+ roles: requiredRoles,
176
+ enable,
177
+ tenantContext,
178
+ rawBody,
179
+ rateLimit,
180
+ base,
181
+ file: path.join(base, defaultConfig.controller || 'controller', handlerParts[0]),
182
+ func: handlerParts[1],
183
+ doc: doc
184
+ }
185
+ }
186
+
187
+ return null
188
+ }
189
+
64
190
  async function load(): Promise<ConfiguredRoute[]> {
65
191
  const validRoutes: ConfiguredRoute[] = []
66
192
  const patterns = normalizePatterns(['..', 'api', '**', 'routes.{ts,js}'], ['src', 'api', '**', 'routes.{ts,js}'])
@@ -84,114 +210,9 @@ async function load(): Promise<ConfiguredRoute[]> {
84
210
  if (log.t) log.trace(`* Add ${routes.length} routes from ${file}`)
85
211
 
86
212
  routes.forEach((route: Route, index: number) => {
87
- const errors: string[] = []
88
- const {
89
- method: methodCase,
90
- path: pathName = '/',
91
- handler,
92
- roles: rs = [],
93
- config = {} as RouteConfig,
94
- middlewares = [],
95
- rateLimit
96
- } = route
97
-
98
- const rsp = !rs.length ? [roles.public] : rs
99
- let requiredRoles: Role[] = []
100
-
101
- try {
102
- requiredRoles = rsp.some((r) => r.code === roles.admin.code) ? rsp : [...rsp, roles.admin]
103
- } catch (err) {
104
- if (log.e) log.error(`Error in loading roles for ${methodCase} ${pathName} (${handler})`)
105
- if (log.t) log.trace(err)
106
- config.enable = false
107
- }
108
-
109
- const reqAuth: boolean =
110
- middlewares.some((m) => authMiddlewares.includes(m)) ||
111
- requiredRoles.every((r) => r.code !== roles.public.code)
112
-
113
- if (!config?.security && reqAuth) {
114
- config.security = 'bearer'
115
- }
116
-
117
- const {
118
- title = '',
119
- description = '',
120
- enable = yn(defaultConfig.enable, true),
121
- deprecated = yn(defaultConfig.deprecated, false),
122
- tags = defaultConfig.tags,
123
- version = defaultConfig.version || '',
124
- security = defaultConfig.security,
125
- query,
126
- params,
127
- body,
128
- response,
129
- consumes,
130
- rawBody = false
131
- } = config || {}
132
-
133
- const endpoint = `${dir}${pathName.replace(/\/+$/, '')}`
134
- const method = methodCase.toUpperCase()
135
- const num = index + 1
136
- const handlerParts = handler.split('.')
137
-
138
- if (enable) {
139
- if (!pathName.startsWith('/')) errors.push(`Error in [${file}] bad path [${pathName}] at route n. ${num}`)
140
- if (!methods.includes(method)) errors.push(`Error in [${file}] bad method [${method}] at route n. ${num}`)
141
- if (handlerParts.length !== 2) errors.push(`Error in [${file}] bad handler [${handler}] at route n. ${num}`)
142
-
143
- const key = method + endpoint + version
144
- if (validRoutes.some((r) => `${r.method}${r.path}${r.doc?.version}` === key)) {
145
- errors.push(`Error in [${file}] duplicated path [${pathName}] at route n. ${num}`)
146
- }
147
-
148
- if (errors.length > 0) {
149
- if (log.e) errors.forEach((error) => log.error(error))
150
- }
151
- }
152
-
153
- const toAdd = enable && errors.length === 0
154
- if (toAdd) {
155
- if (log.t)
156
- log.trace(
157
- `* Method [${method}] path ${endpoint} handler ${handler} enabled with ${
158
- middlewares?.length || 0
159
- } middlewares`
160
- )
161
- } else {
162
- if (log.w) log.warn(`* Method [${method}] path ${endpoint} handler ${handler} disabled. Skip.`)
163
- }
164
-
165
- if (toAdd) {
166
- const doc = {
167
- summary: title,
168
- description,
169
- deprecated,
170
- tags,
171
- version,
172
- security: security === 'bearer' ? [{ Bearer: [] }] : security,
173
- response
174
- } as any
175
-
176
- if (query) doc.querystring = query
177
- if (params) doc.params = params
178
- if (body) doc.body = body
179
- if (consumes) doc.consumes = consumes
180
-
181
- validRoutes.push({
182
- handler,
183
- method,
184
- path: '/' + endpoint,
185
- middlewares,
186
- roles: requiredRoles,
187
- enable,
188
- rawBody,
189
- rateLimit,
190
- base,
191
- file: path.join(base, defaultConfig.controller || 'controller', handlerParts[0]),
192
- func: handlerParts[1],
193
- doc: doc
194
- })
213
+ const configuredRoute = processRoute(route, index, file, dir, base, defaultConfig, authMiddlewares, validRoutes)
214
+ if (configuredRoute) {
215
+ validRoutes.push(configuredRoute)
195
216
  }
196
217
  })
197
218
  }
@@ -211,7 +232,8 @@ async function applyRoutes(server: any, routes: ConfiguredRoute[]): Promise<void
211
232
  let countRoutes = 0
212
233
  for (const route of routes) {
213
234
  if (route?.enable) {
214
- const { handler, method, path, middlewares, roles, rawBody, rateLimit, base, file, func, doc } = route
235
+ const { handler, method, path, middlewares, roles, rawBody, rateLimit, base, file, func, doc, tenantContext } =
236
+ route
215
237
 
216
238
  if (log.d) log.debug(`* Add path ${method} ${path} on handle ${handler}`)
217
239
  const midds = await loadMiddlewares(base, middlewares)
@@ -224,7 +246,8 @@ async function applyRoutes(server: any, routes: ConfiguredRoute[]): Promise<void
224
246
  config: {
225
247
  requiredRoles: roles || [],
226
248
  rawBody: rawBody || false,
227
- rateLimit: rateLimit || undefined
249
+ rateLimit: rateLimit || undefined,
250
+ tenantContext: tenantContext
228
251
  },
229
252
  handler: async function (req: FastifyRequest, reply: FastifyReply) {
230
253
  let module