@qrvey/assets-sharing 0.3.3 → 0.3.4-dev.2089

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 (95) hide show
  1. package/__test__/hasAdminRole.test.ts +146 -47
  2. package/package.json +53 -52
  3. package/src/common/constants.ts +17 -0
  4. package/src/context.ts +12 -0
  5. package/src/index.ts +10 -0
  6. package/src/quser/services/hasAdminRole.ts +11 -5
  7. package/src/sharing/entities/details.ts +1 -0
  8. package/src/sharing/entities/types/organization.type.ts +10 -0
  9. package/src/sharing/implementations/admin.repository.ts +66 -0
  10. package/src/sharing/implementations/organization.model.ts +28 -0
  11. package/src/sharing/implementations/organization.repository.ts +35 -0
  12. package/src/sharing/interfaces/adminRepository.interface.ts +13 -0
  13. package/src/sharing/interfaces/organizationRepository.interface.ts +8 -0
  14. package/src/sharing/services/checkAppPermissions.ts +44 -0
  15. package/src/sharing/services/checkOrgPermissions.ts +29 -0
  16. package/tsconfig.json +25 -17
  17. package/tsup.config.cjs.ts +8 -0
  18. package/dist/cjs/common/common.type.js +0 -3
  19. package/dist/cjs/common/common.type.js.map +0 -1
  20. package/dist/cjs/common/constants.js +0 -48
  21. package/dist/cjs/common/constants.js.map +0 -1
  22. package/dist/cjs/common/persistence/base.js +0 -15
  23. package/dist/cjs/common/persistence/base.js.map +0 -1
  24. package/dist/cjs/common/persistence/poolClient.js +0 -11
  25. package/dist/cjs/common/persistence/poolClient.js.map +0 -1
  26. package/dist/cjs/common/util.js +0 -12
  27. package/dist/cjs/common/util.js.map +0 -1
  28. package/dist/cjs/context.js +0 -18
  29. package/dist/cjs/context.js.map +0 -1
  30. package/dist/cjs/index.js +0 -29
  31. package/dist/cjs/index.js.map +0 -1
  32. package/dist/cjs/quser/entities/types/user.type.js +0 -3
  33. package/dist/cjs/quser/entities/types/user.type.js.map +0 -1
  34. package/dist/cjs/quser/entities/user.js +0 -25
  35. package/dist/cjs/quser/entities/user.js.map +0 -1
  36. package/dist/cjs/quser/implementations/group.model.js +0 -19
  37. package/dist/cjs/quser/implementations/group.model.js.map +0 -1
  38. package/dist/cjs/quser/implementations/group.repository.js +0 -19
  39. package/dist/cjs/quser/implementations/group.repository.js.map +0 -1
  40. package/dist/cjs/quser/implementations/user.model.js +0 -24
  41. package/dist/cjs/quser/implementations/user.model.js.map +0 -1
  42. package/dist/cjs/quser/implementations/user.repository.js +0 -29
  43. package/dist/cjs/quser/implementations/user.repository.js.map +0 -1
  44. package/dist/cjs/quser/interfaces/rolesRepository.interface.js +0 -3
  45. package/dist/cjs/quser/interfaces/rolesRepository.interface.js.map +0 -1
  46. package/dist/cjs/quser/interfaces/userRepository.interface.js +0 -3
  47. package/dist/cjs/quser/interfaces/userRepository.interface.js.map +0 -1
  48. package/dist/cjs/quser/services/fromTokenToUser.js +0 -52
  49. package/dist/cjs/quser/services/fromTokenToUser.js.map +0 -1
  50. package/dist/cjs/quser/services/hasAdminRole.js +0 -44
  51. package/dist/cjs/quser/services/hasAdminRole.js.map +0 -1
  52. package/dist/cjs/sharing/entities/details.js +0 -109
  53. package/dist/cjs/sharing/entities/details.js.map +0 -1
  54. package/dist/cjs/sharing/entities/sharing.js +0 -63
  55. package/dist/cjs/sharing/entities/sharing.js.map +0 -1
  56. package/dist/cjs/sharing/entities/types/details.type.js +0 -3
  57. package/dist/cjs/sharing/entities/types/details.type.js.map +0 -1
  58. package/dist/cjs/sharing/entities/types/sharing.type.js +0 -3
  59. package/dist/cjs/sharing/entities/types/sharing.type.js.map +0 -1
  60. package/dist/cjs/sharing/implementations/details.model.js +0 -93
  61. package/dist/cjs/sharing/implementations/details.model.js.map +0 -1
  62. package/dist/cjs/sharing/implementations/details.repository.js +0 -114
  63. package/dist/cjs/sharing/implementations/details.repository.js.map +0 -1
  64. package/dist/cjs/sharing/implementations/dm.model.js +0 -22
  65. package/dist/cjs/sharing/implementations/dm.model.js.map +0 -1
  66. package/dist/cjs/sharing/implementations/dm.repository.js +0 -20
  67. package/dist/cjs/sharing/implementations/dm.repository.js.map +0 -1
  68. package/dist/cjs/sharing/implementations/dx.model.js +0 -30
  69. package/dist/cjs/sharing/implementations/dx.model.js.map +0 -1
  70. package/dist/cjs/sharing/implementations/dx.repository.js +0 -21
  71. package/dist/cjs/sharing/implementations/dx.repository.js.map +0 -1
  72. package/dist/cjs/sharing/implementations/sharing.model.js +0 -33
  73. package/dist/cjs/sharing/implementations/sharing.model.js.map +0 -1
  74. package/dist/cjs/sharing/implementations/sharing.repository.js +0 -31
  75. package/dist/cjs/sharing/implementations/sharing.repository.js.map +0 -1
  76. package/dist/cjs/sharing/interfaces/dashboardRepository.interface.js +0 -3
  77. package/dist/cjs/sharing/interfaces/dashboardRepository.interface.js.map +0 -1
  78. package/dist/cjs/sharing/interfaces/detailsRepository.interface.js +0 -3
  79. package/dist/cjs/sharing/interfaces/detailsRepository.interface.js.map +0 -1
  80. package/dist/cjs/sharing/interfaces/downloadManagerRepository.interface.js +0 -3
  81. package/dist/cjs/sharing/interfaces/downloadManagerRepository.interface.js.map +0 -1
  82. package/dist/cjs/sharing/interfaces/sharingRepository.interface.js +0 -3
  83. package/dist/cjs/sharing/interfaces/sharingRepository.interface.js.map +0 -1
  84. package/dist/cjs/sharing/services/checkUserAccessLevel.js +0 -58
  85. package/dist/cjs/sharing/services/checkUserAccessLevel.js.map +0 -1
  86. package/dist/cjs/sharing/services/delete.js +0 -32
  87. package/dist/cjs/sharing/services/delete.js.map +0 -1
  88. package/dist/cjs/sharing/services/list.js +0 -44
  89. package/dist/cjs/sharing/services/list.js.map +0 -1
  90. package/dist/cjs/sharing/services/upsert.js +0 -135
  91. package/dist/cjs/sharing/services/upsert.js.map +0 -1
  92. package/dist/cjs/tsconfig.cjs.tsbuildinfo +0 -1
  93. package/dist/esm/index.mjs +0 -1014
  94. package/dist/esm/index.mjs.map +0 -1
  95. package/dist/types/index.d.ts +0 -146
@@ -5,13 +5,19 @@ const loginType = 'qrveyLogin';
5
5
 
6
6
  describe('Check if has admin role.', () => {
7
7
  beforeEach(() => {
8
+ // User Exist
9
+ jest.spyOn(UserRepository.prototype, 'getOne').mockResolvedValue(
10
+ {} as any,
11
+ );
12
+
13
+ // User has no admin role
8
14
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
9
15
  count: 0,
10
16
  items: [],
11
17
  } as any);
12
18
  });
13
19
 
14
- test('Has access with API Key only.', async () => {
20
+ test('Does not have access when: Only API Key', async () => {
15
21
  const body = {
16
22
  apiKey: 'api-key',
17
23
  };
@@ -19,163 +25,224 @@ describe('Check if has admin role.', () => {
19
25
  expect(result).toBe(false);
20
26
  });
21
27
 
22
- test('Has access with API Key and userId.', async () => {
28
+ test('Does not have access when: API Key and Non existing userId', async () => {
29
+ jest.spyOn(UserRepository.prototype, 'getOne').mockResolvedValue(null);
30
+
23
31
  const body = {
24
32
  apiKey: 'api-key',
25
- userId: 'user-id',
33
+ userId: 'non-existing-user',
26
34
  };
27
35
  const result = await hasAdminRole(body);
28
- expect(result).toBe(true);
36
+ expect(result).toBe(false);
29
37
  });
30
38
 
31
- test('Has access with API Key, userId and same clientId as userId.', async () => {
39
+ test('Has access when: API Key and Existing userId', async () => {
32
40
  const body = {
33
41
  apiKey: 'api-key',
34
- userId: 'user-id',
35
- clientId: 'user-id',
42
+ userId: 'existing-user',
36
43
  };
37
44
  const result = await hasAdminRole(body);
38
45
  expect(result).toBe(true);
39
46
  });
40
47
 
41
- test('Has access with API Key, userId, clientId and org:0.', async () => {
48
+ test('Has access when: API Key, org:0 and Existing userId', async () => {
42
49
  const body = {
43
50
  apiKey: 'api-key',
44
- userId: 'user-id',
45
- clientId: 'user-id',
51
+ userId: 'existing-user',
46
52
  orgId: ORGANIZATION_QRVEY,
47
53
  };
48
54
  const result = await hasAdminRole(body);
49
55
  expect(result).toBe(true);
50
56
  });
51
57
 
52
- test('Has no access with another org and apiKey.', async () => {
58
+ test('Does not have access when: API Key, Existing userId and Non existing clientId', async () => {
53
59
  const body = {
54
60
  apiKey: 'api-key',
55
- userId: 'user-id',
56
- clientId: 'user-id',
57
- orgId: 'another-org',
61
+ userId: 'existing-user',
62
+ clientId: 'non-existing-user',
58
63
  };
59
64
  const result = await hasAdminRole(body);
60
65
  expect(result).toBe(false);
61
66
  });
62
67
 
63
- test('Has no access with another org.', async () => {
68
+ test('Has access when: API Key, Existing userId and existing clientId', async () => {
69
+ const body = {
70
+ apiKey: 'api-key',
71
+ userId: 'existing-user',
72
+ clientId: 'existing-user',
73
+ };
74
+ const result = await hasAdminRole(body);
75
+ expect(result).toBe(true);
76
+ });
77
+
78
+ test('Has access when: API Key, no Admin userId and admin clientId', async () => {
64
79
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
65
80
  count: 1,
66
81
  items: [{}],
67
82
  } as any);
83
+
68
84
  const body = {
69
- userId: 'user-id',
70
- clientId: 'user-id',
71
- orgId: 'another-org',
85
+ apiKey: 'api-key',
86
+ userId: 'existing-user',
87
+ clientId: 'admin-user',
72
88
  };
73
89
  const result = await hasAdminRole(body);
74
- expect(result).toBe(false);
90
+ expect(result).toBe(true);
75
91
  });
76
92
 
77
- test('Has no access with another clientId and org.', async () => {
93
+ test('Does not have access when: API Key, org:0 and Existing userId', async () => {
78
94
  const body = {
79
- userId: 'user-id',
80
- clientId: 'another-id',
95
+ apiKey: 'api-key',
96
+ userId: 'existing-user',
81
97
  orgId: 'another-org',
82
98
  };
83
99
  const result = await hasAdminRole(body);
84
100
  expect(result).toBe(false);
85
101
  });
86
102
 
87
- test('Has no access with another clientId.', async () => {
103
+ test('Does not have access when: InComposer only (need userId)', async () => {
88
104
  const body = {
89
- userId: 'user-id',
90
- clientId: 'another-id',
105
+ loginType,
91
106
  };
92
107
  const result = await hasAdminRole(body);
93
108
  expect(result).toBe(false);
94
109
  });
95
110
 
96
- test('Has access with admin user.', async () => {
111
+ test('Has access when: InComposer, org:0 and Admin userId', async () => {
97
112
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
98
113
  count: 1,
99
114
  items: [{}],
100
115
  } as any);
116
+
101
117
  const body = {
102
- userId: 'admin-user',
103
118
  loginType,
119
+ userId: 'admin-user',
120
+ orgId: ORGANIZATION_QRVEY,
104
121
  };
105
122
  const result = await hasAdminRole(body);
106
123
  expect(result).toBe(true);
107
124
  });
108
125
 
109
- test('Has no access with other user.', async () => {
126
+ test('Does not have access when: InComposer, org:0 and non Admin userId', async () => {
110
127
  const body = {
111
- userId: 'other-user',
128
+ loginType,
129
+ userId: 'non-admin-user',
130
+ orgId: ORGANIZATION_QRVEY,
112
131
  };
113
132
  const result = await hasAdminRole(body);
114
133
  expect(result).toBe(false);
115
134
  });
116
135
 
117
- test('Has no access even with admin user but, with another client.', async () => {
136
+ test('Does not have access when: org:0 and Admin userId only', async () => {
137
+ jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
138
+ count: 1,
139
+ items: [{}],
140
+ } as any);
141
+
118
142
  const body = {
119
143
  userId: 'admin-user',
120
- clientId: 'other-user',
144
+ orgId: ORGANIZATION_QRVEY,
121
145
  };
122
146
  const result = await hasAdminRole(body);
123
147
  expect(result).toBe(false);
124
148
  });
125
149
 
126
- test('Has no access even with admin user but, with another client and org.', async () => {
150
+ test('Has access when: org:0, Admin userId and Admin ClientId (same as userId)', async () => {
151
+ jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
152
+ count: 1,
153
+ items: [{}],
154
+ } as any);
155
+
127
156
  const body = {
128
157
  userId: 'admin-user',
129
- clientId: 'other-user',
130
- orgId: 'other-org',
158
+ clientId: 'admin-user',
159
+ orgId: ORGANIZATION_QRVEY,
131
160
  };
132
161
  const result = await hasAdminRole(body);
133
- expect(result).toBe(false);
162
+ expect(result).toBe(true);
163
+ });
164
+
165
+ test('Has access when: org:0, Admin userId and Another Admin ClientId', async () => {
166
+ jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
167
+ count: 1,
168
+ items: [{}],
169
+ } as any);
170
+
171
+ const body = {
172
+ userId: 'admin-user',
173
+ clientId: 'another-admin-user',
174
+ orgId: ORGANIZATION_QRVEY,
175
+ };
176
+ const result = await hasAdminRole(body);
177
+ expect(result).toBe(true);
134
178
  });
135
179
 
136
- test('Has no access even with admin user but, with another client and org0.', async () => {
180
+ test('Does not have access when: org:0, Admin userId and Non Admin ClientId', async () => {
137
181
  const body = {
138
182
  userId: 'admin-user',
139
- clientId: 'other-user',
183
+ clientId: 'non-admin-user',
140
184
  orgId: ORGANIZATION_QRVEY,
141
185
  };
142
186
  const result = await hasAdminRole(body);
143
187
  expect(result).toBe(false);
144
188
  });
145
189
 
146
- test('Has admin level if is in composer', async () => {
190
+ test('Has access when: org:0, non Admin userId and Admin ClientId', async () => {
147
191
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
148
192
  count: 1,
149
193
  items: [{}],
150
194
  } as any);
195
+
151
196
  const body = {
152
- userId: 'admin-user',
197
+ userId: 'non-admin-user',
198
+ clientId: 'admin-user',
153
199
  orgId: ORGANIZATION_QRVEY,
154
- loginType,
155
200
  };
156
201
  const result = await hasAdminRole(body);
157
202
  expect(result).toBe(true);
158
203
  });
159
204
 
160
- test('Has admin level if is not in composer with admin clientId', async () => {
205
+ test('Does not have access when: org:0, non Admin userId and non Admin ClientId', async () => {
206
+ const body = {
207
+ userId: 'non-admin-user',
208
+ clientId: 'another-non-admin-user',
209
+ orgId: ORGANIZATION_QRVEY,
210
+ };
211
+ const result = await hasAdminRole(body);
212
+ expect(result).toBe(false);
213
+ });
214
+
215
+ test('Does not have access when: InComposer, Another org, Admin userId', async () => {
161
216
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
162
217
  count: 1,
163
218
  items: [{}],
164
219
  } as any);
220
+
165
221
  const body = {
166
222
  userId: 'admin-user',
167
- clientId: 'another-admin-user',
168
- orgId: ORGANIZATION_QRVEY,
223
+ orgId: 'another-org',
224
+ loginType,
169
225
  };
170
226
  const result = await hasAdminRole(body);
171
- expect(result).toBe(true);
227
+ expect(result).toBe(false);
172
228
  });
173
229
 
174
- test('Has not admin level if is not in composer with admin clientId but with another org', async () => {
230
+ test('Does not have access when: InComposer, Another org, non Admin userId', async () => {
231
+ const body = {
232
+ userId: 'non-admin-user',
233
+ orgId: 'another-org',
234
+ loginType,
235
+ };
236
+ const result = await hasAdminRole(body);
237
+ expect(result).toBe(false);
238
+ });
239
+
240
+ test('Does not have access when: Another org, Admin userId and Admin clientId', async () => {
175
241
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
176
242
  count: 1,
177
243
  items: [{}],
178
244
  } as any);
245
+
179
246
  const body = {
180
247
  userId: 'admin-user',
181
248
  clientId: 'admin-user',
@@ -185,14 +252,46 @@ describe('Check if has admin role.', () => {
185
252
  expect(result).toBe(false);
186
253
  });
187
254
 
188
- test('Has not admin level if is not in composer and not clientId', async () => {
255
+ test('Does not have access when: Another org, Admin userId and another Admin clientId', async () => {
189
256
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
190
257
  count: 1,
191
258
  items: [{}],
192
259
  } as any);
260
+
193
261
  const body = {
194
262
  userId: 'admin-user',
195
- orgId: ORGANIZATION_QRVEY,
263
+ clientId: 'another-admin-user',
264
+ orgId: 'another-org',
265
+ };
266
+ const result = await hasAdminRole(body);
267
+ expect(result).toBe(false);
268
+ });
269
+
270
+ test('Does not have access when: Another org, Admin userId and non Admin clientId', async () => {
271
+ const body = {
272
+ userId: 'admin-user',
273
+ clientId: 'non-admin-user',
274
+ orgId: 'another-org',
275
+ };
276
+ const result = await hasAdminRole(body);
277
+ expect(result).toBe(false);
278
+ });
279
+
280
+ test('Does not have access when: Another org, non Admin userId and Admin clientId', async () => {
281
+ const body = {
282
+ userId: 'non-admin-user',
283
+ clientId: 'admin-user',
284
+ orgId: 'another-org',
285
+ };
286
+ const result = await hasAdminRole(body);
287
+ expect(result).toBe(false);
288
+ });
289
+
290
+ test('Does not have access when: Another org, non Admin userId and non Admin clientId', async () => {
291
+ const body = {
292
+ userId: 'non-admin-user',
293
+ clientId: 'another-non-admin-user',
294
+ orgId: 'another-org',
196
295
  };
197
296
  const result = await hasAdminRole(body);
198
297
  expect(result).toBe(false);
package/package.json CHANGED
@@ -1,54 +1,55 @@
1
1
  {
2
- "name": "@qrvey/assets-sharing",
3
- "version": "0.3.3",
4
- "types": "dist/types/index.d.ts",
5
- "main": "dist/cjs/index.js",
6
- "exports": {
7
- ".": {
8
- "import": "./dist/esm/index.mjs",
9
- "require": "./dist/cjs/index.js",
10
- "default": "./dist/cjs/index.js"
11
- }
12
- },
13
- "scripts": {
14
- "test": "jest",
15
- "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
16
- "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
17
- "build:clean": "rm -rf dist",
18
- "build:compile:original": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
19
- "build:compile:cjs:original": "tsup --config ./tsup.config.cjs.ts",
20
- "build:compile:cjs": "tsc -b ./tsconfig.cjs.json",
21
- "build:compile:esm": "tsup --config ./tsup.config.esm.ts",
22
- "build:compile:types": "tsup --config ./tsup.config.types.ts",
23
- "build:compile": "yarn build:compile:cjs && yarn build:compile:esm && yarn build:compile:types",
24
- "build": "yarn build:clean && yarn build:compile",
25
- "prepare-publish": "yarn install && yarn build",
26
- "publish-package": "yarn prepare-publish && npm publish"
27
- },
28
- "dependencies": {
29
- "@qrvey/data-persistence": "0.5.1-bundled.1",
30
- "@qrvey/id-generator": "1.0.1",
31
- "reflect-metadata": "0.2.2",
32
- "tsyringe": "4.8.0"
33
- },
34
- "devDependencies": {
35
- "@types/jest": "29.5.14",
36
- "eslint": "8.48.0",
37
- "eslint-import-resolver-typescript": "3.8.0",
38
- "eslint-plugin-import": "2.31.0",
39
- "jest": "29.7.0",
40
- "ts-jest": "29.3.4",
41
- "tsup": "8.0.2",
42
- "typescript": "5.7.3"
43
- },
44
- "keywords": [
45
- "sharing",
46
- "qrvey"
47
- ],
48
- "author": "Qrvey",
49
- "license": "ISC",
50
- "publishConfig": {
51
- "access": "public",
52
- "registry": "https://registry.npmjs.org"
2
+ "name": "@qrvey/assets-sharing",
3
+ "version": "0.3.4-dev.2089",
4
+ "types": "dist/types/index.d.ts",
5
+ "main": "dist/cjs/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./dist/esm/index.mjs",
9
+ "require": "./dist/cjs/index.js",
10
+ "default": "./dist/cjs/index.js"
53
11
  }
54
- }
12
+ },
13
+ "scripts": {
14
+ "test": "jest",
15
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
16
+ "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
17
+ "build:clean": "rm -rf dist",
18
+ "build:compile:original": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
19
+ "build:compile:cjs:original": "tsup --config ./tsup.config.cjs.ts",
20
+ "build:compile:cjs": "tsc -b ./tsconfig.cjs.json",
21
+ "build:compile:esm": "tsup --config ./tsup.config.esm.ts",
22
+ "build:compile:types": "tsup --config ./tsup.config.types.ts",
23
+ "build:compile": "yarn build:compile:cjs && yarn build:compile:esm && yarn build:compile:types",
24
+ "build": "yarn build:clean && yarn build:compile",
25
+ "prepare-publish": "yarn install && yarn build",
26
+ "publish-package": "yarn prepare-publish && npm publish"
27
+ },
28
+ "dependencies": {
29
+ "@qrvey/data-persistence": "0.5.1-bundled.1",
30
+ "@qrvey/id-generator": "^1.0.1",
31
+ "@qrvey/utils": "1.15.0-30",
32
+ "reflect-metadata": "0.2.2",
33
+ "tsyringe": "4.8.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/jest": "29.5.14",
37
+ "eslint": "8.48.0",
38
+ "eslint-import-resolver-typescript": "3.8.0",
39
+ "eslint-plugin-import": "2.31.0",
40
+ "jest": "29.7.0",
41
+ "ts-jest": "29.3.4",
42
+ "tsup": "8.3.5",
43
+ "typescript": "5.7.3"
44
+ },
45
+ "keywords": [
46
+ "sharing",
47
+ "qrvey"
48
+ ],
49
+ "author": "Qrvey",
50
+ "license": "ISC",
51
+ "publishConfig": {
52
+ "access": "public",
53
+ "registry": "https://registry.npmjs.org"
54
+ }
55
+ }
@@ -1,6 +1,8 @@
1
1
  export const ENVIRONMENT = {
2
2
  SERVER_PREFIX: process.env.SERVER_PREFIX,
3
3
  TABLE_PREFIX: process.env.TABLE_PREFIX,
4
+ DOMAIN: process.env.DOMAIN,
5
+ API_KEY: process.env.API_KEY,
4
6
  };
5
7
 
6
8
  export const DATABASE_INFO = {
@@ -44,4 +46,19 @@ export enum ACCESS_LEVEL {
44
46
  ADMIN = 4,
45
47
  }
46
48
 
49
+ export enum AppSharingStatus {
50
+ PUBLIC = 'public',
51
+ PRIVATE = 'private',
52
+ }
53
+
54
+ export interface AppPermissionResponse {
55
+ privacy: AppSharingStatus;
56
+ }
57
+
58
+ export interface AppOwner {
59
+ userId: string;
60
+ appId: string;
61
+ userEmail?: string;
62
+ }
63
+
47
64
  export const LIMIT_PER_PAGE = 10;
package/src/context.ts CHANGED
@@ -12,6 +12,10 @@ import { type DashboardRepositoryInterface } from './sharing/interfaces/dashboar
12
12
  import { type SharingDetailsRepositoryInterface } from './sharing/interfaces/detailsRepository.interface';
13
13
  import { type DownloadManagerRepositoryInterface } from './sharing/interfaces/downloadManagerRepository.interface';
14
14
  import { type SharingRepositoryInterface } from './sharing/interfaces/sharingRepository.interface';
15
+ import { OrganizationRepositoryInterface } from './sharing/interfaces/organizationRepository.interface';
16
+ import { OrganizationRepository } from './sharing/implementations/organization.repository';
17
+ import { AdminRepositoryInterface } from './sharing/interfaces/adminRepository.interface';
18
+ import { AdminRepository } from './sharing/implementations/admin.repository';
15
19
 
16
20
  container.register<SharingRepositoryInterface>(
17
21
  'SharingRepository',
@@ -31,5 +35,13 @@ container.register<DownloadManagerRepositoryInterface>(
31
35
  'dmRepository',
32
36
  DownloadManagerRepository,
33
37
  );
38
+ container.register<OrganizationRepositoryInterface>(
39
+ 'OrganizationRepository',
40
+ OrganizationRepository,
41
+ );
42
+ container.register<AdminRepositoryInterface>(
43
+ 'AdminRepository',
44
+ AdminRepository,
45
+ );
34
46
 
35
47
  export const Context = container;
package/src/index.ts CHANGED
@@ -6,6 +6,8 @@ import { CheckUserAccessLevel } from './sharing/services/checkUserAccessLevel';
6
6
  import { DeleteSharing } from './sharing/services/delete';
7
7
  import { ListSharing } from './sharing/services/list';
8
8
  import { UpsertSharing } from './sharing/services/upsert';
9
+ import CheckAppPermissions from './sharing/services/checkAppPermissions';
10
+ import CheckOrgPermissions from './sharing/services/checkOrgPermissions';
9
11
 
10
12
  export const api = {
11
13
  upsert: (...args: Parameters<UpsertSharing['execute']>) =>
@@ -20,6 +22,14 @@ export const checkUserAccessLevel = (
20
22
  ...args: Parameters<CheckUserAccessLevel['execute']>
21
23
  ) => Context.resolve(CheckUserAccessLevel).execute(...args);
22
24
 
25
+ export const checkAppPermissions = (
26
+ ...args: Parameters<CheckAppPermissions['execute']>
27
+ ) => Context.resolve(CheckAppPermissions).execute(...args);
28
+
29
+ export const checkOrgPermissions = (
30
+ ...args: Parameters<CheckOrgPermissions['execute']>
31
+ ) => Context.resolve(CheckOrgPermissions).execute(...args);
32
+
23
33
  export const fromTokenToUser = (
24
34
  ...args: Parameters<FromTokenToUser['execute']>
25
35
  ) => Context.resolve(FromTokenToUser).execute(...args);
@@ -26,9 +26,18 @@ export class HasAdminRole {
26
26
  } = {}): Promise<boolean> {
27
27
  if (!userId) return false;
28
28
 
29
+ const existingUser = await this.userRepository.getOne(userId);
29
30
  const isMasterKey =
30
31
  apiKey && (orgId === undefined || orgId === ORGANIZATION_QRVEY);
31
- if (isMasterKey) return true;
32
+ if (isMasterKey && existingUser && (!clientId || clientId === userId))
33
+ return true;
34
+
35
+ const user = await this.userRepository.getList({
36
+ data: { identifier: clientId ?? userId, role: 'administrator' },
37
+ });
38
+ const isAdmin = user.items.length > 0;
39
+
40
+ if (isMasterKey && isAdmin) return true;
32
41
 
33
42
  const inComposer = isComposer(loginType || '');
34
43
  const isExternal =
@@ -36,10 +45,7 @@ export class HasAdminRole {
36
45
  (orgId && orgId !== ORGANIZATION_QRVEY);
37
46
  if (isExternal) return false;
38
47
 
39
- const user = await this.userRepository.getList({
40
- data: { identifier: clientId ?? userId, role: 'administrator' },
41
- });
42
- if (user.items.length > 0) return true;
48
+ if (isAdmin) return true;
43
49
 
44
50
  return false;
45
51
  }
@@ -52,6 +52,7 @@ export class SharingDetail {
52
52
  createdAt: now,
53
53
  updatedAt: now,
54
54
  };
55
+
55
56
  return new SharingDetail(obj);
56
57
  }
57
58
 
@@ -0,0 +1,10 @@
1
+ export interface OrganizationType {
2
+ orgid: string;
3
+ name: string;
4
+ parentorgid: string | null;
5
+ org_path: string;
6
+ contentprivacy: boolean;
7
+ effectivecontentprivacy: boolean;
8
+ createdat: string;
9
+ updatedat: string;
10
+ }
@@ -0,0 +1,66 @@
1
+ import { AdminRepositoryInterface } from '../interfaces/adminRepository.interface';
2
+ import { ENVIRONMENT } from '../../common/constants';
3
+ import { getAttribute } from '@qrvey/utils';
4
+
5
+ export class AdminRepository implements AdminRepositoryInterface{
6
+ async getApplicationInfo(body: { appId: string; userId: string }) {
7
+ const url = `${ENVIRONMENT.DOMAIN}/devapi/v4/user/${body.userId}/app/${body.appId}`;
8
+
9
+ const headers = {
10
+ 'x-api-key': ENVIRONMENT.API_KEY as string,
11
+ };
12
+
13
+ const requestOptions: RequestInit = {
14
+ method: 'GET',
15
+ headers,
16
+ };
17
+
18
+ const response = await fetch(url, requestOptions);
19
+
20
+ const data = (await response.json()) as {
21
+ userid?: string;
22
+ appId?: string;
23
+ userEmail?: string;
24
+ };
25
+
26
+ return {
27
+ status: response.status,
28
+ data: {
29
+ userId: data?.userid ?? body.userId,
30
+ appId: getAttribute(data, 'appId'),
31
+ userEmail: getAttribute(data, 'userEmail'),
32
+ },
33
+ };
34
+ }
35
+
36
+ async getPlatformConfiguration(): Promise<{
37
+ status: number;
38
+ legacyMode: boolean;
39
+ }> {
40
+ const url = `${ENVIRONMENT.DOMAIN}/admin/api/v5/customization/features/platform`;
41
+
42
+ const headers = {
43
+ 'x-api-key': ENVIRONMENT.API_KEY as string,
44
+ };
45
+
46
+ const requestOptions: RequestInit = {
47
+ method: 'GET',
48
+ headers,
49
+ };
50
+
51
+ const response = await fetch(url, requestOptions);
52
+
53
+ const data = (await response.json()) as {
54
+ Item: {
55
+ settings: {
56
+ legacyMode: boolean;
57
+ };
58
+ };
59
+ };
60
+ return {
61
+ status: response.status,
62
+ legacyMode: data?.Item?.settings?.legacyMode ?? true,
63
+ };
64
+ }
65
+
66
+ }
@@ -0,0 +1,28 @@
1
+ import { CrudSchema } from '@qrvey/data-persistence';
2
+ import { DATABASE_INFO } from '../../common/constants';
3
+
4
+ export default class OrganizationModel extends CrudSchema {
5
+ static readonly table = {
6
+ name: 'qv_organization',
7
+ alias: `${DATABASE_INFO.TABLE_PREFIX}_organization`,
8
+ };
9
+
10
+ static readonly columns = {
11
+ orgid: { type: 'string', primary: true },
12
+ name: { type: 'string' },
13
+ parentorgid: { type: 'string' },
14
+ org_path: { type: 'string' },
15
+ contentprivacy: { type: 'boolean' },
16
+ effectivecontentprivacy: { type: 'boolean' },
17
+ createdat: { type: 'string' },
18
+ updatedat: { type: 'string' },
19
+ };
20
+
21
+ static readonly indexes = {
22
+ org_path: { name: 'idx_qv_orgs_org_path_gist', columns: ['org_path'] },
23
+ parentorgid: { name: 'idx_qv_orgs_parent', columns: ['parentorgid'] },
24
+ };
25
+
26
+ static readonly schema = DATABASE_INFO.DATA_PERSISTENCE_SCHEMA;
27
+ static readonly usePool = true;
28
+ }