@volcanicminds/backend 2.3.2 → 3.0.1

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 +221 -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 +18 -1
  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 +138 -112
  154. package/lib/loader/tenant.ts +29 -13
  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 +56 -15
  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.connection) {
51
- log.error('Multi-tenant enabled but global.connection not found')
52
- return reply.code(500).send({ statusCode: 500, error: 'Internal Server Error' })
53
- }
54
-
55
- const tenant = await global.connection.getRepository(global.entity.Tenant).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
-
@@ -53,14 +53,143 @@ async function loadMiddleware(base: string, middleware: string = '') {
53
53
  }
54
54
 
55
55
  async function loadMiddlewares(base: string, middlewares: string[] = []) {
56
- const midds = {}
56
+ const midds: { [key: string]: any[] } = {}
57
57
  for (const m of middlewares) {
58
58
  const middleware = await loadMiddleware(base, m)
59
- Object.keys(middleware).map((name) => (midds[name] = [...(midds[name] || []), middleware[name]]))
59
+ for (const name in middleware) {
60
+ if (!midds[name]) midds[name] = []
61
+ midds[name].push(middleware[name])
62
+ }
60
63
  }
61
64
  return midds
62
65
  }
63
66
 
67
+
68
+ function processRoute(
69
+ route: Route,
70
+ index: number,
71
+ file: string,
72
+ dir: string,
73
+ base: string,
74
+ defaultConfig: any,
75
+ authMiddlewares: string[],
76
+ validRoutes: ConfiguredRoute[]
77
+ ): ConfiguredRoute | null {
78
+ const errors: string[] = []
79
+ const {
80
+ method: methodCase,
81
+ path: pathName = '/',
82
+ handler,
83
+ roles: rs = [],
84
+ config = {} as RouteConfig,
85
+ middlewares = [],
86
+ rateLimit
87
+ } = route
88
+
89
+ const rsp = !rs.length ? [roles.public] : rs
90
+ let requiredRoles: Role[] = []
91
+
92
+ try {
93
+ requiredRoles = rsp.some((r) => r.code === roles.admin.code) ? rsp : [...rsp, roles.admin]
94
+ } catch (err) {
95
+ if (log.e) log.error(`Error in loading roles for ${methodCase} ${pathName} (${handler})`)
96
+ if (log.t) log.trace(err)
97
+ config.enable = false
98
+ }
99
+
100
+ const reqAuth: boolean =
101
+ middlewares.some((m) => authMiddlewares.includes(m)) ||
102
+ requiredRoles.every((r) => r.code !== roles.public.code)
103
+
104
+ if (!config?.security && reqAuth) {
105
+ config.security = 'bearer'
106
+ }
107
+
108
+ const {
109
+ title = '',
110
+ description = '',
111
+ enable = yn(defaultConfig.enable, true),
112
+ deprecated = yn(defaultConfig.deprecated, false),
113
+ tenantContext = yn(defaultConfig.tenantContext, true),
114
+ tags = defaultConfig.tags,
115
+ version = defaultConfig.version || '',
116
+ security = defaultConfig.security,
117
+ query,
118
+ params,
119
+ body,
120
+ response,
121
+ consumes,
122
+ rawBody = false
123
+ } = config || {}
124
+
125
+ const endpoint = `${dir}${pathName.replace(/\/+$/, '')}`
126
+ const method = methodCase.toUpperCase()
127
+ const num = index + 1
128
+ const handlerParts = handler.split('.')
129
+
130
+ if (enable) {
131
+ if (!pathName.startsWith('/')) errors.push(`Error in [${file}] bad path [${pathName}] at route n. ${num}`)
132
+ if (!methods.includes(method)) errors.push(`Error in [${file}] bad method [${method}] at route n. ${num}`)
133
+ if (handlerParts.length !== 2) errors.push(`Error in [${file}] bad handler [${handler}] at route n. ${num}`)
134
+
135
+ const key = method + endpoint + version
136
+ if (validRoutes.some((r) => `${r.method}${r.path}${r.doc?.version}` === key)) {
137
+ errors.push(`Error in [${file}] duplicated path [${pathName}] at route n. ${num}`)
138
+ }
139
+
140
+ if (errors.length > 0) {
141
+ if (log.e) errors.forEach((error) => log.error(error))
142
+ }
143
+ }
144
+
145
+ const toAdd = enable && errors.length === 0
146
+ if (toAdd) {
147
+ if (log.t)
148
+ log.trace(
149
+ `* Method [${method}] path ${endpoint} handler ${handler} enabled with ${
150
+ middlewares?.length || 0
151
+ } middlewares`
152
+ )
153
+ } else {
154
+ if (log.w) log.warn(`* Method [${method}] path ${endpoint} handler ${handler} disabled. Skip.`)
155
+ }
156
+
157
+ if (toAdd) {
158
+ const doc = {
159
+ summary: title,
160
+ description,
161
+ deprecated,
162
+ tags,
163
+ version,
164
+ security: security === 'bearer' ? [{ Bearer: [] }] : security,
165
+ response
166
+ } as any
167
+
168
+ if (query) doc.querystring = query
169
+ if (params) doc.params = params
170
+ if (body) doc.body = body
171
+ if (consumes) doc.consumes = consumes
172
+
173
+ return {
174
+ handler,
175
+ method,
176
+ path: '/' + endpoint,
177
+ middlewares,
178
+ roles: requiredRoles,
179
+ enable,
180
+ tenantContext,
181
+ rawBody,
182
+ rateLimit,
183
+ base,
184
+ file: path.join(base, defaultConfig.controller || 'controller', handlerParts[0]),
185
+ func: handlerParts[1],
186
+ doc: doc
187
+ }
188
+ }
189
+
190
+ return null
191
+ }
192
+
64
193
  async function load(): Promise<ConfiguredRoute[]> {
65
194
  const validRoutes: ConfiguredRoute[] = []
66
195
  const patterns = normalizePatterns(['..', 'api', '**', 'routes.{ts,js}'], ['src', 'api', '**', 'routes.{ts,js}'])
@@ -84,114 +213,9 @@ async function load(): Promise<ConfiguredRoute[]> {
84
213
  if (log.t) log.trace(`* Add ${routes.length} routes from ${file}`)
85
214
 
86
215
  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
- })
216
+ const configuredRoute = processRoute(route, index, file, dir, base, defaultConfig, authMiddlewares, validRoutes)
217
+ if (configuredRoute) {
218
+ validRoutes.push(configuredRoute)
195
219
  }
196
220
  })
197
221
  }
@@ -211,7 +235,8 @@ async function applyRoutes(server: any, routes: ConfiguredRoute[]): Promise<void
211
235
  let countRoutes = 0
212
236
  for (const route of routes) {
213
237
  if (route?.enable) {
214
- const { handler, method, path, middlewares, roles, rawBody, rateLimit, base, file, func, doc } = route
238
+ const { handler, method, path, middlewares, roles, rawBody, rateLimit, base, file, func, doc, tenantContext } =
239
+ route
215
240
 
216
241
  if (log.d) log.debug(`* Add path ${method} ${path} on handle ${handler}`)
217
242
  const midds = await loadMiddlewares(base, middlewares)
@@ -224,7 +249,8 @@ async function applyRoutes(server: any, routes: ConfiguredRoute[]): Promise<void
224
249
  config: {
225
250
  requiredRoles: roles || [],
226
251
  rawBody: rawBody || false,
227
- rateLimit: rateLimit || undefined
252
+ rateLimit: rateLimit || undefined,
253
+ tenantContext: tenantContext
228
254
  },
229
255
  handler: async function (req: FastifyRequest, reply: FastifyReply) {
230
256
  let module