@qrvey/assets-sharing 0.3.2 → 0.3.4-dev.2086

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 (94) hide show
  1. package/__test__/hasAdminRole.test.ts +151 -53
  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 +12 -9
  7. package/src/sharing/entities/types/organization.type.ts +10 -0
  8. package/src/sharing/implementations/admin.repository.ts +66 -0
  9. package/src/sharing/implementations/organization.model.ts +28 -0
  10. package/src/sharing/implementations/organization.repository.ts +35 -0
  11. package/src/sharing/interfaces/adminRepository.interface.ts +13 -0
  12. package/src/sharing/interfaces/organizationRepository.interface.ts +8 -0
  13. package/src/sharing/services/checkAppPermissions.ts +44 -0
  14. package/src/sharing/services/checkOrgPermissions.ts +29 -0
  15. package/tsconfig.json +25 -17
  16. package/tsup.config.cjs.ts +8 -0
  17. package/dist/cjs/common/common.type.js +0 -3
  18. package/dist/cjs/common/common.type.js.map +0 -1
  19. package/dist/cjs/common/constants.js +0 -48
  20. package/dist/cjs/common/constants.js.map +0 -1
  21. package/dist/cjs/common/persistence/base.js +0 -15
  22. package/dist/cjs/common/persistence/base.js.map +0 -1
  23. package/dist/cjs/common/persistence/poolClient.js +0 -11
  24. package/dist/cjs/common/persistence/poolClient.js.map +0 -1
  25. package/dist/cjs/common/util.js +0 -12
  26. package/dist/cjs/common/util.js.map +0 -1
  27. package/dist/cjs/context.js +0 -18
  28. package/dist/cjs/context.js.map +0 -1
  29. package/dist/cjs/index.js +0 -29
  30. package/dist/cjs/index.js.map +0 -1
  31. package/dist/cjs/quser/entities/types/user.type.js +0 -3
  32. package/dist/cjs/quser/entities/types/user.type.js.map +0 -1
  33. package/dist/cjs/quser/entities/user.js +0 -25
  34. package/dist/cjs/quser/entities/user.js.map +0 -1
  35. package/dist/cjs/quser/implementations/group.model.js +0 -19
  36. package/dist/cjs/quser/implementations/group.model.js.map +0 -1
  37. package/dist/cjs/quser/implementations/group.repository.js +0 -19
  38. package/dist/cjs/quser/implementations/group.repository.js.map +0 -1
  39. package/dist/cjs/quser/implementations/user.model.js +0 -24
  40. package/dist/cjs/quser/implementations/user.model.js.map +0 -1
  41. package/dist/cjs/quser/implementations/user.repository.js +0 -29
  42. package/dist/cjs/quser/implementations/user.repository.js.map +0 -1
  43. package/dist/cjs/quser/interfaces/rolesRepository.interface.js +0 -3
  44. package/dist/cjs/quser/interfaces/rolesRepository.interface.js.map +0 -1
  45. package/dist/cjs/quser/interfaces/userRepository.interface.js +0 -3
  46. package/dist/cjs/quser/interfaces/userRepository.interface.js.map +0 -1
  47. package/dist/cjs/quser/services/fromTokenToUser.js +0 -52
  48. package/dist/cjs/quser/services/fromTokenToUser.js.map +0 -1
  49. package/dist/cjs/quser/services/hasAdminRole.js +0 -47
  50. package/dist/cjs/quser/services/hasAdminRole.js.map +0 -1
  51. package/dist/cjs/sharing/entities/details.js +0 -109
  52. package/dist/cjs/sharing/entities/details.js.map +0 -1
  53. package/dist/cjs/sharing/entities/sharing.js +0 -63
  54. package/dist/cjs/sharing/entities/sharing.js.map +0 -1
  55. package/dist/cjs/sharing/entities/types/details.type.js +0 -3
  56. package/dist/cjs/sharing/entities/types/details.type.js.map +0 -1
  57. package/dist/cjs/sharing/entities/types/sharing.type.js +0 -3
  58. package/dist/cjs/sharing/entities/types/sharing.type.js.map +0 -1
  59. package/dist/cjs/sharing/implementations/details.model.js +0 -93
  60. package/dist/cjs/sharing/implementations/details.model.js.map +0 -1
  61. package/dist/cjs/sharing/implementations/details.repository.js +0 -114
  62. package/dist/cjs/sharing/implementations/details.repository.js.map +0 -1
  63. package/dist/cjs/sharing/implementations/dm.model.js +0 -22
  64. package/dist/cjs/sharing/implementations/dm.model.js.map +0 -1
  65. package/dist/cjs/sharing/implementations/dm.repository.js +0 -20
  66. package/dist/cjs/sharing/implementations/dm.repository.js.map +0 -1
  67. package/dist/cjs/sharing/implementations/dx.model.js +0 -30
  68. package/dist/cjs/sharing/implementations/dx.model.js.map +0 -1
  69. package/dist/cjs/sharing/implementations/dx.repository.js +0 -21
  70. package/dist/cjs/sharing/implementations/dx.repository.js.map +0 -1
  71. package/dist/cjs/sharing/implementations/sharing.model.js +0 -33
  72. package/dist/cjs/sharing/implementations/sharing.model.js.map +0 -1
  73. package/dist/cjs/sharing/implementations/sharing.repository.js +0 -31
  74. package/dist/cjs/sharing/implementations/sharing.repository.js.map +0 -1
  75. package/dist/cjs/sharing/interfaces/dashboardRepository.interface.js +0 -3
  76. package/dist/cjs/sharing/interfaces/dashboardRepository.interface.js.map +0 -1
  77. package/dist/cjs/sharing/interfaces/detailsRepository.interface.js +0 -3
  78. package/dist/cjs/sharing/interfaces/detailsRepository.interface.js.map +0 -1
  79. package/dist/cjs/sharing/interfaces/downloadManagerRepository.interface.js +0 -3
  80. package/dist/cjs/sharing/interfaces/downloadManagerRepository.interface.js.map +0 -1
  81. package/dist/cjs/sharing/interfaces/sharingRepository.interface.js +0 -3
  82. package/dist/cjs/sharing/interfaces/sharingRepository.interface.js.map +0 -1
  83. package/dist/cjs/sharing/services/checkUserAccessLevel.js +0 -58
  84. package/dist/cjs/sharing/services/checkUserAccessLevel.js.map +0 -1
  85. package/dist/cjs/sharing/services/delete.js +0 -32
  86. package/dist/cjs/sharing/services/delete.js.map +0 -1
  87. package/dist/cjs/sharing/services/list.js +0 -44
  88. package/dist/cjs/sharing/services/list.js.map +0 -1
  89. package/dist/cjs/sharing/services/upsert.js +0 -135
  90. package/dist/cjs/sharing/services/upsert.js.map +0 -1
  91. package/dist/cjs/tsconfig.cjs.tsbuildinfo +0 -1
  92. package/dist/esm/index.mjs +0 -1014
  93. package/dist/esm/index.mjs.map +0 -1
  94. package/dist/types/index.d.ts +0 -146
@@ -4,7 +4,20 @@ import { UserRepository } from '../src/quser/implementations/user.repository';
4
4
  const loginType = 'qrveyLogin';
5
5
 
6
6
  describe('Check if has admin role.', () => {
7
- test('Has access with API Key only.', async () => {
7
+ beforeEach(() => {
8
+ // User Exist
9
+ jest.spyOn(UserRepository.prototype, 'getOne').mockResolvedValue(
10
+ {} as any,
11
+ );
12
+
13
+ // User has no admin role
14
+ jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
15
+ count: 0,
16
+ items: [],
17
+ } as any);
18
+ });
19
+
20
+ test('Does not have access when: Only API Key', async () => {
8
21
  const body = {
9
22
  apiKey: 'api-key',
10
23
  };
@@ -12,188 +25,273 @@ describe('Check if has admin role.', () => {
12
25
  expect(result).toBe(false);
13
26
  });
14
27
 
15
- 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
+
16
31
  const body = {
17
32
  apiKey: 'api-key',
18
- userId: 'user-id',
33
+ userId: 'non-existing-user',
19
34
  };
20
35
  const result = await hasAdminRole(body);
21
- expect(result).toBe(true);
36
+ expect(result).toBe(false);
22
37
  });
23
38
 
24
- test('Has access with API Key, userId and same clientId as userId.', async () => {
39
+ test('Has access when: API Key and Existing userId', async () => {
25
40
  const body = {
26
41
  apiKey: 'api-key',
27
- userId: 'user-id',
28
- clientId: 'user-id',
42
+ userId: 'existing-user',
29
43
  };
30
44
  const result = await hasAdminRole(body);
31
45
  expect(result).toBe(true);
32
46
  });
33
47
 
34
- 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 () => {
35
49
  const body = {
36
50
  apiKey: 'api-key',
37
- userId: 'user-id',
38
- clientId: 'user-id',
51
+ userId: 'existing-user',
39
52
  orgId: ORGANIZATION_QRVEY,
40
53
  };
41
54
  const result = await hasAdminRole(body);
42
55
  expect(result).toBe(true);
43
56
  });
44
57
 
45
- test('Has access with API Key, userId, clientId and org:0.', async () => {
58
+ test('Does not have access when: API Key, Existing userId and Non existing clientId', async () => {
46
59
  const body = {
47
- userId: 'user-id',
48
- clientId: 'other-id',
49
- orgId: ORGANIZATION_QRVEY,
60
+ apiKey: 'api-key',
61
+ userId: 'existing-user',
62
+ clientId: 'non-existing-user',
50
63
  };
51
64
  const result = await hasAdminRole(body);
52
65
  expect(result).toBe(false);
53
66
  });
54
67
 
55
- test('Has no access with another org and apiKey.', async () => {
68
+ test('Has access when: API Key, Existing userId and existing clientId', async () => {
56
69
  const body = {
57
70
  apiKey: 'api-key',
58
- userId: 'user-id',
59
- clientId: 'user-id',
60
- orgId: 'Another-Org',
71
+ userId: 'existing-user',
72
+ clientId: 'existing-user',
61
73
  };
62
74
  const result = await hasAdminRole(body);
63
- expect(result).toBe(false);
75
+ expect(result).toBe(true);
64
76
  });
65
77
 
66
- test('Has no access with another org.', async () => {
78
+ test('Has access when: API Key, no Admin userId and admin clientId', async () => {
79
+ jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
80
+ count: 1,
81
+ items: [{}],
82
+ } as any);
83
+
67
84
  const body = {
68
- userId: 'user-id',
69
- clientId: 'user-id',
70
- orgId: 'Another-Org',
85
+ apiKey: 'api-key',
86
+ userId: 'existing-user',
87
+ clientId: 'admin-user',
71
88
  };
72
89
  const result = await hasAdminRole(body);
73
- expect(result).toBe(false);
90
+ expect(result).toBe(true);
74
91
  });
75
92
 
76
- 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 () => {
77
94
  const body = {
78
- userId: 'user-id',
79
- clientId: 'another-id',
95
+ apiKey: 'api-key',
96
+ userId: 'existing-user',
80
97
  orgId: 'another-org',
81
98
  };
82
99
  const result = await hasAdminRole(body);
83
100
  expect(result).toBe(false);
84
101
  });
85
102
 
86
- test('Has no access with another clientId.', async () => {
103
+ test('Does not have access when: InComposer only (need userId)', async () => {
87
104
  const body = {
88
- userId: 'user-id',
89
- clientId: 'another-id',
105
+ loginType,
90
106
  };
91
107
  const result = await hasAdminRole(body);
92
108
  expect(result).toBe(false);
93
109
  });
94
110
 
95
- test('Has access with admin user.', async () => {
111
+ test('Has access when: InComposer, org:0 and Admin userId', async () => {
96
112
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
97
113
  count: 1,
98
114
  items: [{}],
99
115
  } as any);
116
+
100
117
  const body = {
101
- userId: 'admin-user',
102
118
  loginType,
119
+ userId: 'admin-user',
120
+ orgId: ORGANIZATION_QRVEY,
103
121
  };
104
122
  const result = await hasAdminRole(body);
105
123
  expect(result).toBe(true);
106
124
  });
107
125
 
108
- test('Has no access with other user.', async () => {
126
+ test('Does not have access when: InComposer, org:0 and non Admin userId', async () => {
127
+ const body = {
128
+ loginType,
129
+ userId: 'non-admin-user',
130
+ orgId: ORGANIZATION_QRVEY,
131
+ };
132
+ const result = await hasAdminRole(body);
133
+ expect(result).toBe(false);
134
+ });
135
+
136
+ test('Does not have access when: org:0 and Admin userId only', async () => {
109
137
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
110
- count: 0,
111
- items: [],
138
+ count: 1,
139
+ items: [{}],
112
140
  } as any);
141
+
113
142
  const body = {
114
- userId: 'other-user',
143
+ userId: 'admin-user',
144
+ orgId: ORGANIZATION_QRVEY,
115
145
  };
116
146
  const result = await hasAdminRole(body);
117
147
  expect(result).toBe(false);
118
148
  });
119
149
 
120
- test('Has no access even with admin user but, with another client.', async () => {
150
+ test('Has access when: org:0, Admin userId and Admin ClientId (same as userId)', async () => {
121
151
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
122
152
  count: 1,
123
153
  items: [{}],
124
154
  } as any);
155
+
125
156
  const body = {
126
157
  userId: 'admin-user',
127
- clientId: 'other-user',
158
+ clientId: 'admin-user',
159
+ orgId: ORGANIZATION_QRVEY,
128
160
  };
129
161
  const result = await hasAdminRole(body);
130
- expect(result).toBe(false);
162
+ expect(result).toBe(true);
131
163
  });
132
164
 
133
- test('Has no access even with admin user but, with another client and org.', async () => {
165
+ test('Has access when: org:0, Admin userId and Another Admin ClientId', async () => {
134
166
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
135
167
  count: 1,
136
168
  items: [{}],
137
169
  } as any);
170
+
138
171
  const body = {
139
172
  userId: 'admin-user',
140
- clientId: 'other-user',
141
- orgId: 'other-org',
173
+ clientId: 'another-admin-user',
174
+ orgId: ORGANIZATION_QRVEY,
175
+ };
176
+ const result = await hasAdminRole(body);
177
+ expect(result).toBe(true);
178
+ });
179
+
180
+ test('Does not have access when: org:0, Admin userId and Non Admin ClientId', async () => {
181
+ const body = {
182
+ userId: 'admin-user',
183
+ clientId: 'non-admin-user',
184
+ orgId: ORGANIZATION_QRVEY,
142
185
  };
143
186
  const result = await hasAdminRole(body);
144
187
  expect(result).toBe(false);
145
188
  });
146
189
 
147
- test('Has no access even with admin user but, with another client and org0.', async () => {
190
+ test('Has access when: org:0, non Admin userId and Admin ClientId', async () => {
148
191
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
149
192
  count: 1,
150
193
  items: [{}],
151
194
  } as any);
195
+
152
196
  const body = {
153
- userId: 'admin-user',
154
- clientId: 'other-user',
197
+ userId: 'non-admin-user',
198
+ clientId: 'admin-user',
199
+ orgId: ORGANIZATION_QRVEY,
200
+ };
201
+ const result = await hasAdminRole(body);
202
+ expect(result).toBe(true);
203
+ });
204
+
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',
155
209
  orgId: ORGANIZATION_QRVEY,
156
210
  };
157
211
  const result = await hasAdminRole(body);
158
212
  expect(result).toBe(false);
159
213
  });
160
214
 
161
- test('Has admin level if is in composer', async () => {
215
+ test('Does not have access when: InComposer, Another org, Admin userId', async () => {
162
216
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
163
217
  count: 1,
164
218
  items: [{}],
165
219
  } as any);
220
+
166
221
  const body = {
167
222
  userId: 'admin-user',
168
- orgId: ORGANIZATION_QRVEY,
223
+ orgId: 'another-org',
169
224
  loginType,
170
225
  };
171
226
  const result = await hasAdminRole(body);
172
- expect(result).toBe(true);
227
+ expect(result).toBe(false);
228
+ });
229
+
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);
173
238
  });
174
239
 
175
- test('Has admin level if is not in composer with clientId', async () => {
240
+ test('Does not have access when: Another org, Admin userId and Admin clientId', async () => {
176
241
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
177
242
  count: 1,
178
243
  items: [{}],
179
244
  } as any);
245
+
180
246
  const body = {
181
247
  userId: 'admin-user',
182
248
  clientId: 'admin-user',
183
- orgId: ORGANIZATION_QRVEY,
249
+ orgId: 'another-org',
184
250
  };
185
251
  const result = await hasAdminRole(body);
186
- expect(result).toBe(true);
252
+ expect(result).toBe(false);
187
253
  });
188
254
 
189
- 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 () => {
190
256
  jest.spyOn(UserRepository.prototype, 'getList').mockResolvedValue({
191
257
  count: 1,
192
258
  items: [{}],
193
259
  } as any);
260
+
194
261
  const body = {
195
262
  userId: 'admin-user',
196
- 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',
197
295
  };
198
296
  const result = await hasAdminRole(body);
199
297
  expect(result).toBe(false);
package/package.json CHANGED
@@ -1,54 +1,55 @@
1
1
  {
2
- "name": "@qrvey/assets-sharing",
3
- "version": "0.3.2",
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.2086",
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": "workspace:*",
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,23 +26,26 @@ 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
- apiKey &&
31
- (clientId === userId || !clientId) &&
32
- (orgId === undefined || orgId === ORGANIZATION_QRVEY);
33
- if (isMasterKey) return true;
31
+ apiKey && (orgId === undefined || orgId === ORGANIZATION_QRVEY);
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;
34
41
 
35
42
  const inComposer = isComposer(loginType || '');
36
43
  const isExternal =
37
44
  (!clientId && !inComposer) ||
38
- (clientId && clientId !== userId) ||
39
45
  (orgId && orgId !== ORGANIZATION_QRVEY);
40
46
  if (isExternal) return false;
41
47
 
42
- const user = await this.userRepository.getList({
43
- data: { identifier: userId, role: 'administrator' },
44
- });
45
- if (user.items.length > 0) return true;
48
+ if (isAdmin) return true;
46
49
 
47
50
  return false;
48
51
  }
@@ -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
+ }