@drax/media-back 2.11.0 → 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 (66) hide show
  1. package/dist/controllers/FileController.js +38 -0
  2. package/dist/controllers/MediaController.js +42 -1
  3. package/dist/factory/services/FileServiceFactory.js +30 -0
  4. package/dist/index.js +13 -2
  5. package/dist/interfaces/IFile.js +1 -0
  6. package/dist/interfaces/IFileRepository.js +1 -0
  7. package/dist/models/FileModel.js +49 -0
  8. package/dist/permissions/FilePermissions.js +13 -0
  9. package/dist/repository/mongo/FileMongoRepository.js +13 -0
  10. package/dist/repository/sqlite/FileSqliteRepository.js +37 -0
  11. package/dist/routes/FileRoutes.js +20 -0
  12. package/dist/schemas/FileSchema.js +51 -0
  13. package/dist/services/FileService.js +22 -0
  14. package/package.json +4 -4
  15. package/src/controllers/FileController.ts +50 -0
  16. package/src/controllers/MediaController.ts +48 -4
  17. package/src/factory/services/FileServiceFactory.ts +41 -0
  18. package/src/index.ts +30 -3
  19. package/src/interfaces/IFile.ts +67 -0
  20. package/src/interfaces/IFileRepository.ts +11 -0
  21. package/src/models/FileModel.ts +65 -0
  22. package/src/permissions/FilePermissions.ts +17 -0
  23. package/src/repository/mongo/FileMongoRepository.ts +22 -0
  24. package/src/repository/sqlite/FileSqliteRepository.ts +46 -0
  25. package/src/routes/FileRoutes.ts +36 -0
  26. package/src/schemas/FileSchema.ts +55 -0
  27. package/src/services/FileService.ts +36 -0
  28. package/test/modules/media/File/File-endpoints.test.ts +573 -0
  29. package/test/setup/MongoInMemory.ts +56 -0
  30. package/test/setup/TestSetup.ts +347 -0
  31. package/test/setup/data/admin-role.ts +13 -0
  32. package/test/setup/data/basic-user.ts +14 -0
  33. package/test/setup/data/file-role.ts +16 -0
  34. package/test/setup/data/one-tenant.ts +6 -0
  35. package/test/setup/data/restricted-role.ts +11 -0
  36. package/test/setup/data/root-user.ts +14 -0
  37. package/test/setup/data/tenant-one-user.ts +13 -0
  38. package/test/setup/data/tenant-two-user.ts +14 -0
  39. package/test/setup/data/two-tenant.ts +6 -0
  40. package/test/utils/StoreManager.test.ts +1 -1
  41. package/tsconfig.tsbuildinfo +1 -1
  42. package/types/controllers/FileController.d.ts +10 -0
  43. package/types/controllers/FileController.d.ts.map +1 -0
  44. package/types/controllers/MediaController.d.ts.map +1 -1
  45. package/types/factory/services/FileServiceFactory.d.ts +8 -0
  46. package/types/factory/services/FileServiceFactory.d.ts.map +1 -0
  47. package/types/index.d.ts +13 -1
  48. package/types/index.d.ts.map +1 -1
  49. package/types/interfaces/IFile.d.ts +63 -0
  50. package/types/interfaces/IFile.d.ts.map +1 -0
  51. package/types/interfaces/IFileRepository.d.ts +6 -0
  52. package/types/interfaces/IFileRepository.d.ts.map +1 -0
  53. package/types/models/FileModel.d.ts +15 -0
  54. package/types/models/FileModel.d.ts.map +1 -0
  55. package/types/permissions/FilePermissions.d.ts +13 -0
  56. package/types/permissions/FilePermissions.d.ts.map +1 -0
  57. package/types/repository/mongo/FileMongoRepository.d.ts +9 -0
  58. package/types/repository/mongo/FileMongoRepository.d.ts.map +1 -0
  59. package/types/repository/sqlite/FileSqliteRepository.d.ts +18 -0
  60. package/types/repository/sqlite/FileSqliteRepository.d.ts.map +1 -0
  61. package/types/routes/FileRoutes.d.ts +4 -0
  62. package/types/routes/FileRoutes.d.ts.map +1 -0
  63. package/types/schemas/FileSchema.d.ts +65 -0
  64. package/types/schemas/FileSchema.d.ts.map +1 -0
  65. package/types/services/FileService.d.ts +12 -0
  66. package/types/services/FileService.d.ts.map +1 -0
@@ -0,0 +1,347 @@
1
+ import Fastify, { FastifyInstance, FastifyPluginAsync } from "fastify";
2
+ import { LoadCommonConfigFromEnv } from "@drax/common-back";
3
+ import {
4
+ LoadIdentityConfigFromEnv,
5
+ CreateTenantIfNotExist,
6
+ CreateOrUpdateRole,
7
+ CreateUserIfNotExist,
8
+ jwtMiddleware,
9
+ rbacMiddleware,
10
+ apiKeyMiddleware,
11
+ UserRoutes, RoleRoutes, TenantRoutes, UserApiKeyRoutes,
12
+ UserPermissions, RolePermissions, TenantPermissions, UserApiKeyPermissions,
13
+ LoadPermissions
14
+ } from "@drax/identity-back";
15
+
16
+
17
+ import adminRoleData from "./data/admin-role";
18
+ import restrictedRoleData from "./data/restricted-role";
19
+ import fileRoleData from "./data/file-role";
20
+
21
+ import rootUserData from "./data/root-user";
22
+ import basicUserData from "./data/basic-user";
23
+
24
+ import { IUser, IRole, ITenant } from "@drax/identity-share";
25
+ import MongoInMemory from "./MongoInMemory";
26
+
27
+ import oneTenant from "./data/one-tenant";
28
+ import twoTenant from "./data/two-tenant";
29
+ import tenantOneUser from "./data/tenant-one-user";
30
+ import tenantTwoUser from "./data/tenant-two-user";
31
+
32
+ interface ITestSetupInput {
33
+ routes?: FastifyPluginAsync[]
34
+ permissions?: object[]
35
+ }
36
+
37
+ class TestSetup {
38
+
39
+ private _fastifyInstance: FastifyInstance;
40
+ private _mongoInMemory: MongoInMemory;
41
+ private _rootUser: IUser;
42
+ private _basicUser: IUser;
43
+ private _adminRole: IRole;
44
+ private _restrictedRole: IRole;
45
+ private _customRoutes: FastifyPluginAsync[] = [];
46
+ private _customPermissions: object[] = [];
47
+
48
+ private _tenantOne: ITenant;
49
+ private _tenantTwo: ITenant;
50
+ private _tenantOneUser: IUser;
51
+ private _tenantTwoUser: IUser;
52
+
53
+ constructor(input?: ITestSetupInput) {
54
+ this._customRoutes = input?.routes ?? [];
55
+ this._customPermissions = input?.permissions ?? [];
56
+ }
57
+
58
+ async setup() {
59
+ this.setupEnvironmentVariables();
60
+ this.setupConfig();
61
+ this.setupPermissions();
62
+ this.setupFastifyInstance();
63
+ await this.setupMongoInMemoryAndConnect();
64
+ await this.setupRootUserAndAdminRole();
65
+ await this.setupBasicUserAndRestrictedRole();
66
+ await this.setupFileRole();
67
+ await this.setupTenantOneAndTenantOneUser();
68
+ await this.setupTenantTwoAndTenantTwoUser();
69
+ }
70
+
71
+ setupEnvironmentVariables() {
72
+ // Define environment variables
73
+ process.env.DRAX_DB_ENGINE = "mongo";
74
+ process.env.DRAX_JWT_SECRET = "xxx";
75
+ }
76
+
77
+ setupConfig() {
78
+ LoadCommonConfigFromEnv();
79
+ LoadIdentityConfigFromEnv();
80
+ }
81
+
82
+ setupPermissions() {
83
+ //Merge All Permissions
84
+ const permissions = [
85
+ ...Object.values(UserPermissions),
86
+ ...Object.values(RolePermissions),
87
+ ...Object.values(TenantPermissions),
88
+ ...Object.values(UserApiKeyPermissions),
89
+ ...this.getCustomPermissions()
90
+ ]
91
+
92
+ //Load All Permissions
93
+ LoadPermissions(permissions)
94
+ }
95
+
96
+ getCustomPermissions() {
97
+ const customPermissions = []
98
+ for (const permission of this._customPermissions) {
99
+ customPermissions.push(...Object.values(permission))
100
+ }
101
+ return customPermissions
102
+ }
103
+
104
+ setupFastifyInstance() {
105
+ this._fastifyInstance = Fastify()
106
+ this._fastifyInstance.setErrorHandler(function (error: any, request, reply) {
107
+ console.error("TEST FASTIFY ERROR CAUGHT:", error);
108
+ reply.status(500).send({ statusCode: 500, error: "InternalServerError", message: error?.message });
109
+ });
110
+ this._fastifyInstance.setValidatorCompiler(() => () => true)
111
+ this._fastifyInstance.addHook('onRequest', jwtMiddleware)
112
+ this._fastifyInstance.addHook('onRequest', rbacMiddleware)
113
+ this._fastifyInstance.addHook('onRequest', apiKeyMiddleware)
114
+ this._fastifyInstance.register(UserRoutes)
115
+ this._fastifyInstance.register(RoleRoutes)
116
+ this._fastifyInstance.register(TenantRoutes)
117
+ this._fastifyInstance.register(UserApiKeyRoutes)
118
+ this.registerRoutes(this._customRoutes)
119
+ }
120
+
121
+ registerRoutes(routes: FastifyPluginAsync[]) {
122
+ for (const route of routes) {
123
+ this._fastifyInstance.register(route)
124
+ }
125
+ }
126
+
127
+ async setupMongoInMemoryAndConnect() {
128
+ this._mongoInMemory = new MongoInMemory();
129
+ await this._mongoInMemory.connect();
130
+ }
131
+
132
+ async setupTenantOneAndTenantOneUser() {
133
+ this._tenantOne = await CreateTenantIfNotExist(oneTenant)
134
+ this._tenantOneUser = await CreateUserIfNotExist({ ...tenantOneUser })
135
+ }
136
+
137
+ async setupTenantTwoAndTenantTwoUser() {
138
+ this._tenantTwo = await CreateTenantIfNotExist(twoTenant)
139
+ this._tenantTwoUser = await CreateUserIfNotExist({ ...tenantTwoUser })
140
+ }
141
+
142
+ async setupRootUserAndAdminRole() {
143
+ this._adminRole = await CreateOrUpdateRole({ ...adminRoleData })
144
+ this._rootUser = await CreateUserIfNotExist({ ...rootUserData })
145
+ }
146
+
147
+ async setupBasicUserAndRestrictedRole() {
148
+ this._restrictedRole = await CreateOrUpdateRole({ ...restrictedRoleData })
149
+ this._basicUser = await CreateUserIfNotExist({ ...basicUserData })
150
+ }
151
+
152
+ async setupFileRole() {
153
+ this._restrictedRole = await CreateOrUpdateRole({ ...fileRoleData })
154
+ }
155
+
156
+ addRoutes(routes) {
157
+ this._fastifyInstance.register(routes)
158
+ }
159
+
160
+ addPermissions(permissions: object) {
161
+ LoadPermissions([...Object.values(permissions)])
162
+ }
163
+
164
+ async dropCollections() {
165
+ await this._mongoInMemory.dropCollections()
166
+ }
167
+
168
+ async dropCollection(collectionName: string) {
169
+ await this._mongoInMemory.dropCollection(collectionName)
170
+ }
171
+
172
+ async dropAndClose() {
173
+ await this._mongoInMemory.dropAndClose()
174
+ }
175
+
176
+ async login(username: string, password: string): Promise<{ accessToken: string }> {
177
+
178
+ const resp = await this._fastifyInstance.inject({
179
+ method: 'POST',
180
+ url: '/api/auth/login',
181
+ payload: { username: username, password: password }
182
+ });
183
+
184
+ let body = resp.json()
185
+
186
+ if (resp.statusCode === 200 && body.accessToken) {
187
+ return { accessToken: body.accessToken }
188
+ } else {
189
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
190
+ }
191
+
192
+ }
193
+
194
+ async rootUserLogin(): Promise<{ accessToken: string }> {
195
+
196
+ const resp = await this._fastifyInstance.inject({
197
+ method: 'POST',
198
+ url: '/api/auth/login',
199
+ payload: {
200
+ username: rootUserData.username,
201
+ password: rootUserData.password
202
+ }
203
+ });
204
+
205
+ let body = resp.json()
206
+
207
+ if (resp.statusCode === 200 && body.accessToken) {
208
+ return { accessToken: body.accessToken }
209
+ } else {
210
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
211
+ }
212
+ }
213
+
214
+ async basicUserLogin(): Promise<{ accessToken: string }> {
215
+
216
+ const resp = await this._fastifyInstance.inject({
217
+ method: 'POST',
218
+ url: '/api/auth/login',
219
+ payload: {
220
+ username: basicUserData.username,
221
+ password: basicUserData.password
222
+ }
223
+ });
224
+
225
+ let body = resp.json()
226
+
227
+ if (resp.statusCode === 200 && body.accessToken) {
228
+ return { accessToken: body.accessToken }
229
+ } else {
230
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
231
+ }
232
+ }
233
+
234
+ async tenantOneUserLogin(): Promise<{ accessToken: string }> {
235
+ const resp = await this._fastifyInstance.inject({
236
+ method: 'POST',
237
+ url: '/api/auth/login',
238
+ payload: {
239
+ username: tenantOneUser.username,
240
+ password: tenantOneUser.password
241
+ }
242
+ });
243
+
244
+ let body = resp.json()
245
+
246
+ if (resp.statusCode === 200 && body.accessToken) {
247
+ return { accessToken: body.accessToken }
248
+ } else {
249
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
250
+ }
251
+ }
252
+
253
+ async tenantTwoUserLogin(): Promise<{ accessToken: string }> {
254
+ const resp = await this._fastifyInstance.inject({
255
+ method: 'POST',
256
+ url: '/api/auth/login',
257
+ payload: {
258
+ username: tenantTwoUser.username,
259
+ password: tenantTwoUser.password
260
+ }
261
+ });
262
+
263
+ let body = resp.json()
264
+
265
+ if (resp.statusCode === 200 && body.accessToken) {
266
+ return { accessToken: body.accessToken }
267
+ } else {
268
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
269
+ }
270
+ }
271
+
272
+ async me(accessToken: string): Promise<IUser> {
273
+
274
+ const resp = await this._fastifyInstance.inject({
275
+ method: 'GET',
276
+ url: '/api/auth/me',
277
+ headers: { Authorization: `Bearer ${accessToken}` }
278
+ });
279
+
280
+ if (resp.statusCode === 200) {
281
+ let user: IUser = resp.json() as IUser
282
+ return user
283
+ } else {
284
+ throw new Error(`Failed to get me. Status Code: ${resp.statusCode} body: ${resp.body}`)
285
+ }
286
+
287
+
288
+ }
289
+
290
+
291
+ get adminRoleData() {
292
+ return { ...adminRoleData };
293
+ }
294
+
295
+ get restrictedRoleData() {
296
+ return { ...restrictedRoleData };
297
+ }
298
+
299
+ get rootUserData() {
300
+ return { ...rootUserData };
301
+ }
302
+
303
+ get basicUserData() {
304
+ return { ...basicUserData };
305
+ }
306
+
307
+ get tenantOneUserData() {
308
+ return { ...tenantOneUser };
309
+ }
310
+
311
+ get tenantTwoUserData() {
312
+ return { ...tenantTwoUser };
313
+ }
314
+
315
+ get adminRole() {
316
+ return this._adminRole;
317
+ }
318
+
319
+ get restrictedRole() {
320
+ return this._restrictedRole;
321
+ }
322
+
323
+ get rootUser() {
324
+ return this._rootUser;
325
+ }
326
+
327
+ get basicUser() {
328
+ return this._basicUser;
329
+ }
330
+
331
+ get fastifyInstance() {
332
+ return this._fastifyInstance;
333
+ }
334
+
335
+ get mongoInMemory() {
336
+ return this._mongoInMemory;
337
+ }
338
+
339
+
340
+ }
341
+
342
+
343
+ export default TestSetup
344
+
345
+ export {
346
+ TestSetup
347
+ }
@@ -0,0 +1,13 @@
1
+ import {PermissionService} from "@drax/identity-back"
2
+
3
+ const adminRoleData = {
4
+ name: "Admin",
5
+ permissions: PermissionService.getPermissions(),
6
+ childRoles: [],
7
+ readonly: true
8
+ }
9
+
10
+ export default adminRoleData
11
+ export {
12
+ adminRoleData
13
+ }
@@ -0,0 +1,14 @@
1
+
2
+ const basicUser = {
3
+ active: true,
4
+ groups: [],
5
+ name: "Basic User",
6
+ username: "basicUser",
7
+ password: "basic.123",
8
+ email: "basic@example.com",
9
+ phone: "123456789",
10
+ role: "Restricted"
11
+ };
12
+
13
+ export default basicUser
14
+ export {basicUser}
@@ -0,0 +1,16 @@
1
+ import FilePermissions from "../../../src/permissions/FilePermissions";
2
+
3
+ const restrictedRoleData = {
4
+ name: "FileRole",
5
+ permissions: [
6
+ FilePermissions.View,
7
+ FilePermissions.Create,
8
+ FilePermissions.Update,
9
+ FilePermissions.Delete,
10
+ ],
11
+ childRoles: [],
12
+ readonly: true
13
+ }
14
+
15
+ export default restrictedRoleData
16
+ export {restrictedRoleData}
@@ -0,0 +1,6 @@
1
+ const oneTenant = {
2
+ name: "one",
3
+ };
4
+
5
+ export default oneTenant
6
+ export {oneTenant}
@@ -0,0 +1,11 @@
1
+
2
+ const restrictedRoleData = {
3
+ name: "Restricted",
4
+ permissions: [
5
+ ],
6
+ childRoles: [],
7
+ readonly: true
8
+ }
9
+
10
+ export default restrictedRoleData
11
+ export {restrictedRoleData}
@@ -0,0 +1,14 @@
1
+
2
+ const rootUser = {
3
+ active: true,
4
+ groups: [],
5
+ name: "Root",
6
+ username: "root",
7
+ password: "root.123",
8
+ email: "root@example.com",
9
+ phone: "123456789",
10
+ role: "Admin"
11
+ };
12
+
13
+ export default rootUser
14
+ export {rootUser}
@@ -0,0 +1,13 @@
1
+ const tenantOneUser = {
2
+ active: true,
3
+ name: "TenantOneUser",
4
+ username: "tenantoneuser",
5
+ password: "123456789",
6
+ email: "tenantoneuser@example.com",
7
+ phone: "123456789",
8
+ role: "FileRole",
9
+ tenant: 'one'
10
+ };
11
+
12
+ export default tenantOneUser
13
+ export {tenantOneUser}
@@ -0,0 +1,14 @@
1
+
2
+ const tenantTwoUser = {
3
+ active: true,
4
+ name: "TenantTwoUser",
5
+ username: "tenanttwouser",
6
+ password: "123456789",
7
+ email: "tenanttwouser@example.com",
8
+ phone: "123456789",
9
+ role: "FileRole",
10
+ tenant: 'two'
11
+ };
12
+
13
+ export default tenantTwoUser
14
+ export {tenantTwoUser}
@@ -0,0 +1,6 @@
1
+ const twoTenant = {
2
+ name: "two",
3
+ };
4
+
5
+ export default twoTenant
6
+ export {twoTenant}
@@ -5,7 +5,7 @@ import type {IUploadFile} from "../../../../common/common-back/src/interfaces/IU
5
5
  import {join} from "path";
6
6
  import UploadFileError from "../../../../common/common-back/src/errors/UploadFileError";
7
7
  import StoreManager from "../../../../common/common-back/src/store/StoreManager";
8
- import path from "path";
8
+ import * as path from "path";
9
9
  import {fileURLToPath} from "url";
10
10
 
11
11
  const __dirname = path.dirname(fileURLToPath(import.meta.url));