@mondaydotcomorg/monday-authorization 3.5.2-feat-shaime-support-entity-attributes-4-ddec1d3 → 3.5.2-feat-shaime-support-entity-attributes-3-00b45ac
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.
- package/dist/authorization-attributes-ms-service.d.ts +1 -17
- package/dist/authorization-attributes-ms-service.d.ts.map +1 -1
- package/dist/authorization-attributes-ms-service.js +47 -58
- package/dist/authorization-attributes-sns-service.d.ts +2 -23
- package/dist/authorization-attributes-sns-service.d.ts.map +1 -1
- package/dist/authorization-attributes-sns-service.js +11 -49
- package/dist/base-attribute-assignment.d.ts +6 -7
- package/dist/base-attribute-assignment.d.ts.map +1 -1
- package/dist/base-attribute-assignment.js +5 -7
- package/dist/entity-attribute-assignment.d.ts +4 -8
- package/dist/entity-attribute-assignment.d.ts.map +1 -1
- package/dist/entity-attribute-assignment.js +4 -3
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +0 -1
- package/dist/esm/authorization-attributes-ms-service.d.ts +1 -17
- package/dist/esm/authorization-attributes-ms-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-ms-service.mjs +47 -58
- package/dist/esm/authorization-attributes-sns-service.d.ts +2 -23
- package/dist/esm/authorization-attributes-sns-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-sns-service.mjs +11 -49
- package/dist/esm/base-attribute-assignment.d.ts +6 -7
- package/dist/esm/base-attribute-assignment.d.ts.map +1 -1
- package/dist/esm/base-attribute-assignment.mjs +5 -7
- package/dist/esm/entity-attribute-assignment.d.ts +4 -8
- package/dist/esm/entity-attribute-assignment.d.ts.map +1 -1
- package/dist/esm/entity-attribute-assignment.mjs +4 -3
- package/dist/esm/errors/argument-error.d.ts.map +1 -1
- package/dist/esm/errors/argument-error.mjs +0 -1
- package/dist/esm/resource-attribute-assignment.d.ts +3 -7
- package/dist/esm/resource-attribute-assignment.d.ts.map +1 -1
- package/dist/esm/resource-attribute-assignment.mjs +3 -2
- package/dist/esm/resource-attributes-constants.d.ts +9 -9
- package/dist/esm/resource-attributes-constants.d.ts.map +1 -1
- package/dist/esm/resource-attributes-constants.mjs +2 -2
- package/dist/esm/testKit/index.d.ts +4 -4
- package/dist/esm/testKit/index.d.ts.map +1 -1
- package/dist/esm/types/authorization-attributes-contracts.d.ts +1 -2
- package/dist/esm/types/authorization-attributes-contracts.d.ts.map +1 -1
- package/dist/esm/types/authorization-attributes-service.interface.d.ts +2 -16
- package/dist/esm/types/authorization-attributes-service.interface.d.ts.map +1 -1
- package/dist/esm/types/general.d.ts +1 -1
- package/dist/esm/types/general.d.ts.map +1 -1
- package/dist/esm/utils/assigment-schema.d.ts +23 -0
- package/dist/esm/utils/assigment-schema.d.ts.map +1 -0
- package/dist/esm/utils/assigment-schema.mjs +29 -0
- package/dist/esm/utils/resource-schema.d.ts +17 -0
- package/dist/esm/utils/resource-schema.d.ts.map +1 -0
- package/dist/esm/utils/resource-schema.mjs +16 -0
- package/dist/esm/utils/validation.d.ts +9 -28
- package/dist/esm/utils/validation.d.ts.map +1 -1
- package/dist/esm/utils/validation.mjs +47 -120
- package/dist/resource-attribute-assignment.d.ts +3 -7
- package/dist/resource-attribute-assignment.d.ts.map +1 -1
- package/dist/resource-attribute-assignment.js +3 -2
- package/dist/resource-attributes-constants.d.ts +9 -9
- package/dist/resource-attributes-constants.d.ts.map +1 -1
- package/dist/resource-attributes-constants.js +2 -2
- package/dist/testKit/index.d.ts +4 -4
- package/dist/testKit/index.d.ts.map +1 -1
- package/dist/types/authorization-attributes-contracts.d.ts +1 -2
- package/dist/types/authorization-attributes-contracts.d.ts.map +1 -1
- package/dist/types/authorization-attributes-service.interface.d.ts +2 -16
- package/dist/types/authorization-attributes-service.interface.d.ts.map +1 -1
- package/dist/types/general.d.ts +1 -1
- package/dist/types/general.d.ts.map +1 -1
- package/dist/utils/assigment-schema.d.ts +23 -0
- package/dist/utils/assigment-schema.d.ts.map +1 -0
- package/dist/utils/assigment-schema.js +36 -0
- package/dist/utils/resource-schema.d.ts +17 -0
- package/dist/utils/resource-schema.d.ts.map +1 -0
- package/dist/utils/resource-schema.js +22 -0
- package/dist/utils/validation.d.ts +9 -28
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +47 -120
- package/package.json +2 -3
- package/src/authorization-attributes-ms-service.ts +93 -117
- package/src/authorization-attributes-sns-service.ts +14 -69
- package/src/base-attribute-assignment.ts +10 -26
- package/src/entity-attribute-assignment.ts +9 -6
- package/src/errors/argument-error.ts +0 -1
- package/src/resource-attribute-assignment.ts +10 -12
- package/src/resource-attributes-constants.ts +2 -2
- package/src/testKit/index.ts +5 -5
- package/src/types/authorization-attributes-contracts.ts +1 -1
- package/src/types/authorization-attributes-service.interface.ts +2 -33
- package/src/types/general.ts +1 -1
- package/src/utils/assigment-schema.ts +29 -0
- package/src/utils/resource-schema.ts +21 -0
- package/src/utils/validation.ts +60 -138
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
AttributeOperation,
|
|
7
7
|
ResourceAttributeOperation,
|
|
8
8
|
EntityAttributeOperation,
|
|
9
|
+
ResourceAttributeResponse,
|
|
9
10
|
} from './types/authorization-attributes-contracts';
|
|
10
11
|
import { EntityType } from './entity-attributes-constants';
|
|
11
|
-
import { ArgumentError } from './errors/argument-error';
|
|
12
12
|
import { AuthorizationInternalService, logger } from './authorization-internal-service';
|
|
13
13
|
import { getAttributionsFromApi } from './attributions-service';
|
|
14
14
|
import { APP_NAME } from './constants';
|
|
15
15
|
import { ValidationUtils } from './utils/validation';
|
|
16
16
|
import { AuthorizationAttributesService } from './types/authorization-attributes-service.interface';
|
|
17
17
|
import { Resource } from './types/general';
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
const INTERNAL_APP_NAME = 'internal_ms';
|
|
20
20
|
const UPSERT_RESOURCE_ATTRIBUTES_PATH = '/attributes/{accountId}/resource';
|
|
21
21
|
const DELETE_RESOURCE_ATTRIBUTES_PATH = '/attributes/{accountId}/resource/{resourceType}/{resourceId}';
|
|
@@ -32,34 +32,7 @@ interface DeleteRequestBody {
|
|
|
32
32
|
*/
|
|
33
33
|
export class AuthorizationAttributesMsService implements AuthorizationAttributesService {
|
|
34
34
|
private static LOG_TAG = 'authorization_attributes_ms';
|
|
35
|
-
private static httpClient: HttpClient |
|
|
36
|
-
|
|
37
|
-
public static destroyHttpClient(): void {
|
|
38
|
-
AuthorizationAttributesMsService.httpClient = null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Creates or updates resource attributes synchronously.
|
|
43
|
-
* @param accountId The account ID
|
|
44
|
-
* @param resourceAttributeAssignments Array of ResourceAttributeAssignment objects
|
|
45
|
-
* @returns Promise<void>
|
|
46
|
-
*/
|
|
47
|
-
async upsertResourceAttributes(
|
|
48
|
-
accountId: number,
|
|
49
|
-
resourceAttributeAssignments: ResourceAttributeAssignment[],
|
|
50
|
-
_appName?: string,
|
|
51
|
-
_callerActionIdentifier?: string
|
|
52
|
-
): Promise<void> {
|
|
53
|
-
return AuthorizationAttributesMsService.executeUpsertRequest(
|
|
54
|
-
accountId,
|
|
55
|
-
resourceAttributeAssignments,
|
|
56
|
-
UPSERT_RESOURCE_ATTRIBUTES_PATH,
|
|
57
|
-
'resourceAttributeAssignments',
|
|
58
|
-
ResourceAttributeAssignment,
|
|
59
|
-
'resource',
|
|
60
|
-
'upsertResourceAttributes'
|
|
61
|
-
);
|
|
62
|
-
}
|
|
35
|
+
private static httpClient: HttpClient | undefined = Api.getPart('httpClient');
|
|
63
36
|
|
|
64
37
|
/**
|
|
65
38
|
* Deletes specific attributes from a resource synchronously.
|
|
@@ -76,41 +49,16 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
76
49
|
_callerActionIdentifier?: string
|
|
77
50
|
): Promise<void> {
|
|
78
51
|
ValidationUtils.validateResource(resource);
|
|
79
|
-
ValidationUtils.validateStringArray(attributeKeys);
|
|
80
52
|
return AuthorizationAttributesMsService.executeDeleteRequest(
|
|
81
53
|
accountId,
|
|
82
54
|
DELETE_RESOURCE_ATTRIBUTES_PATH,
|
|
83
55
|
{
|
|
84
56
|
resourceType: resource.type,
|
|
85
|
-
resourceId: resource.id
|
|
57
|
+
resourceId: resource.id,
|
|
86
58
|
},
|
|
87
59
|
attributeKeys,
|
|
88
60
|
'resource',
|
|
89
|
-
'deleteResourceAttributesSync'
|
|
90
|
-
{ resource }
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Creates or updates entity attributes synchronously.
|
|
96
|
-
* @param accountId The account ID
|
|
97
|
-
* @param entityAttributeAssignments Array of EntityAttributeAssignment objects
|
|
98
|
-
* @returns Promise<void>
|
|
99
|
-
*/
|
|
100
|
-
async upsertEntityAttributes(
|
|
101
|
-
accountId: number,
|
|
102
|
-
entityAttributeAssignments: EntityAttributeAssignment[],
|
|
103
|
-
_appName?: string,
|
|
104
|
-
_callerActionIdentifier?: string
|
|
105
|
-
): Promise<void> {
|
|
106
|
-
return AuthorizationAttributesMsService.executeUpsertRequest(
|
|
107
|
-
accountId,
|
|
108
|
-
entityAttributeAssignments,
|
|
109
|
-
UPSERT_ENTITY_ATTRIBUTES_PATH,
|
|
110
|
-
'entityAttributeAssignments',
|
|
111
|
-
EntityAttributeAssignment,
|
|
112
|
-
'entity',
|
|
113
|
-
'upsertEntityAttributesSync'
|
|
61
|
+
'deleteResourceAttributesSync'
|
|
114
62
|
);
|
|
115
63
|
}
|
|
116
64
|
|
|
@@ -130,11 +78,7 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
130
78
|
_appName?: string,
|
|
131
79
|
_callerActionIdentifier?: string
|
|
132
80
|
): Promise<void> {
|
|
133
|
-
|
|
134
|
-
throw new ArgumentError(`entityType must be a non-empty string, got: ${entityType}`);
|
|
135
|
-
}
|
|
136
|
-
ValidationUtils.validateInteger(entityId);
|
|
137
|
-
|
|
81
|
+
ValidationUtils.validateInteger(accountId);
|
|
138
82
|
return AuthorizationAttributesMsService.executeDeleteRequest(
|
|
139
83
|
accountId,
|
|
140
84
|
DELETE_ENTITY_ATTRIBUTES_PATH,
|
|
@@ -144,8 +88,7 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
144
88
|
},
|
|
145
89
|
attributeKeys,
|
|
146
90
|
'entity',
|
|
147
|
-
'deleteEntityAttributesSync'
|
|
148
|
-
{ entityType, entityId }
|
|
91
|
+
'deleteEntityAttributesSync'
|
|
149
92
|
);
|
|
150
93
|
}
|
|
151
94
|
|
|
@@ -165,39 +108,38 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
165
108
|
_callerActionIdentifier: string,
|
|
166
109
|
resourceAttributeOperations: ResourceAttributeOperation[]
|
|
167
110
|
): Promise<ResourceAttributeOperation[]> {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
111
|
+
// Process all operations in parallel using Promise.all
|
|
112
|
+
await Promise.all(
|
|
113
|
+
resourceAttributeOperations.map(async operation => {
|
|
114
|
+
ValidationUtils.validateResourceAssignment({
|
|
115
|
+
resourceId: operation.resourceId,
|
|
116
|
+
resourceType: operation.resourceType,
|
|
117
|
+
key: operation.key,
|
|
118
|
+
value: operation.value || '',
|
|
119
|
+
});
|
|
120
|
+
if (operation.operationType === AttributeOperation.UPSERT) {
|
|
121
|
+
await this.upsertResourceAttributes(accountId, [
|
|
122
|
+
new ResourceAttributeAssignment(
|
|
123
|
+
operation.resourceId,
|
|
124
|
+
operation.resourceType,
|
|
125
|
+
operation.key,
|
|
126
|
+
operation.value || ''
|
|
127
|
+
),
|
|
128
|
+
]);
|
|
129
|
+
} else if (operation.operationType === AttributeOperation.DELETE) {
|
|
130
|
+
await this.deleteResourceAttributes(
|
|
131
|
+
accountId,
|
|
132
|
+
{
|
|
133
|
+
type: operation.resourceType,
|
|
134
|
+
id: operation.resourceId,
|
|
135
|
+
},
|
|
136
|
+
[operation.key]
|
|
137
|
+
);
|
|
174
138
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
operation.resourceId,
|
|
178
|
-
operation.resourceType,
|
|
179
|
-
operation.key,
|
|
180
|
-
operation.value || ''
|
|
181
|
-
),
|
|
182
|
-
]);
|
|
183
|
-
processedOperations.push(operation);
|
|
184
|
-
} else if (operation.operationType === AttributeOperation.DELETE) {
|
|
185
|
-
if (!operation.resourceId) {
|
|
186
|
-
throw new ArgumentError('resourceId is required for delete operation');
|
|
187
|
-
}
|
|
188
|
-
await this.deleteResourceAttributes(
|
|
189
|
-
accountId,
|
|
190
|
-
{
|
|
191
|
-
type: operation.resourceType,
|
|
192
|
-
id: operation.resourceId,
|
|
193
|
-
},
|
|
194
|
-
[operation.key]
|
|
195
|
-
);
|
|
196
|
-
processedOperations.push(operation);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
139
|
+
})
|
|
140
|
+
);
|
|
199
141
|
|
|
200
|
-
return
|
|
142
|
+
return resourceAttributeOperations;
|
|
201
143
|
}
|
|
202
144
|
|
|
203
145
|
/**
|
|
@@ -216,20 +158,40 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
216
158
|
_callerActionIdentifier: string,
|
|
217
159
|
entityAttributeOperations: EntityAttributeOperation[]
|
|
218
160
|
): Promise<EntityAttributeOperation[]> {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
161
|
+
// Process all operations in parallel using Promise.all
|
|
162
|
+
await Promise.all(
|
|
163
|
+
entityAttributeOperations.map(async operation => {
|
|
164
|
+
// Validate before processing
|
|
165
|
+
ValidationUtils.validateEntityAssignment({
|
|
166
|
+
entityId: operation.entityId,
|
|
167
|
+
entityType: operation.entityType,
|
|
168
|
+
key: operation.key,
|
|
169
|
+
value: operation.value || '',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
if (operation.operationType === 'upsert') {
|
|
173
|
+
await AuthorizationAttributesMsService.executeUpsertRequest(
|
|
174
|
+
accountId,
|
|
175
|
+
[
|
|
176
|
+
new EntityAttributeAssignment(
|
|
177
|
+
operation.entityId,
|
|
178
|
+
operation.entityType,
|
|
179
|
+
operation.key,
|
|
180
|
+
operation.value || ''
|
|
181
|
+
),
|
|
182
|
+
],
|
|
183
|
+
UPSERT_ENTITY_ATTRIBUTES_PATH,
|
|
184
|
+
'entityAttributeAssignments',
|
|
185
|
+
'entity',
|
|
186
|
+
'upsertEntityAttributesSync'
|
|
187
|
+
);
|
|
188
|
+
} else if (operation.operationType === 'delete') {
|
|
189
|
+
await this.deleteEntityAttributes(accountId, operation.entityType, operation.entityId, [operation.key]);
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
);
|
|
231
193
|
|
|
232
|
-
return
|
|
194
|
+
return entityAttributeOperations;
|
|
233
195
|
}
|
|
234
196
|
|
|
235
197
|
/**
|
|
@@ -255,8 +217,7 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
255
217
|
pathParams: Record<string, string | number>,
|
|
256
218
|
keys: string[],
|
|
257
219
|
logPrefix: string,
|
|
258
|
-
methodName: string
|
|
259
|
-
context: Record<string, any> = {}
|
|
220
|
+
methodName: string
|
|
260
221
|
): Promise<void> {
|
|
261
222
|
// Validate inputs
|
|
262
223
|
ValidationUtils.validateInteger(accountId);
|
|
@@ -307,7 +268,6 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
307
268
|
method: methodName,
|
|
308
269
|
accountId,
|
|
309
270
|
...pathParams,
|
|
310
|
-
...context,
|
|
311
271
|
error: err instanceof Error ? err.message : String(err),
|
|
312
272
|
},
|
|
313
273
|
`Failed in ${methodName}`
|
|
@@ -374,15 +334,9 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
374
334
|
assignments: T[],
|
|
375
335
|
pathTemplate: string,
|
|
376
336
|
requestBodyKey: 'resourceAttributeAssignments' | 'entityAttributeAssignments',
|
|
377
|
-
assignmentClass: abstract new (...args: any[]) => T,
|
|
378
337
|
logPrefix: string,
|
|
379
338
|
methodName: string
|
|
380
339
|
): Promise<void> {
|
|
381
|
-
ValidationUtils.validateInteger(accountId);
|
|
382
|
-
ValidationUtils.validateArrayTypeOf(assignments, assignmentClass);
|
|
383
|
-
if (!assignments.length) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
340
|
const assignmentDto = assignments.map(assignment => assignment.toDataTransferObject());
|
|
387
341
|
|
|
388
342
|
const requestBody =
|
|
@@ -435,4 +389,26 @@ export class AuthorizationAttributesMsService implements AuthorizationAttributes
|
|
|
435
389
|
throw err;
|
|
436
390
|
}
|
|
437
391
|
}
|
|
392
|
+
|
|
393
|
+
private async upsertResourceAttributes(
|
|
394
|
+
accountId: number,
|
|
395
|
+
resourceAttributeAssignments: ResourceAttributeAssignment[]
|
|
396
|
+
): Promise<ResourceAttributeResponse> {
|
|
397
|
+
const attributionHeaders = getAttributionsFromApi();
|
|
398
|
+
if (!AuthorizationAttributesMsService.httpClient) {
|
|
399
|
+
throw new Error('AuthorizationAttributesMsService: HTTP client is not initialized');
|
|
400
|
+
}
|
|
401
|
+
return await AuthorizationAttributesMsService.httpClient.fetch<ResourceAttributeResponse>({
|
|
402
|
+
url: {
|
|
403
|
+
appName: APP_NAME,
|
|
404
|
+
path: UPSERT_RESOURCE_ATTRIBUTES_PATH.replace('{accountId}', accountId.toString()),
|
|
405
|
+
},
|
|
406
|
+
method: 'POST',
|
|
407
|
+
headers: {
|
|
408
|
+
'Content-Type': 'application/json',
|
|
409
|
+
...attributionHeaders,
|
|
410
|
+
},
|
|
411
|
+
body: JSON.stringify({ resourceAttributeAssignments }),
|
|
412
|
+
});
|
|
413
|
+
}
|
|
438
414
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import chunk from 'lodash/chunk.js';
|
|
2
2
|
import { getTopicAttributes, sendToSns } from '@mondaydotcomorg/monday-sns';
|
|
3
3
|
import {
|
|
4
|
-
ResourceAttributeAssignment,
|
|
5
4
|
ResourceAttributeOperation,
|
|
6
5
|
EntityAttributeOperation,
|
|
7
6
|
AttributeOperation,
|
|
8
7
|
} from './types/authorization-attributes-contracts';
|
|
9
|
-
import { EntityAttributeAssignment } from './entity-attribute-assignment';
|
|
10
8
|
import { Resource } from './types/general';
|
|
11
9
|
import { logger } from './authorization-internal-service';
|
|
12
10
|
import {
|
|
@@ -20,9 +18,10 @@ import {
|
|
|
20
18
|
ENTITY_SNS_DEV_TEST_NAME,
|
|
21
19
|
SnsTopicType,
|
|
22
20
|
} from './constants/sns';
|
|
23
|
-
import type { TopicAttributesMap } from 'aws-sdk/clients/sns';
|
|
24
21
|
import { AuthorizationAttributesService } from './types/authorization-attributes-service.interface';
|
|
25
22
|
import { EntityType } from './entity-attributes-constants';
|
|
23
|
+
import { ValidationUtils } from './utils/validation';
|
|
24
|
+
import type { TopicAttributesMap } from 'aws-sdk/clients/sns';
|
|
26
25
|
|
|
27
26
|
/**
|
|
28
27
|
* Service class for managing resource attributes asynchronously via SNS.
|
|
@@ -41,31 +40,6 @@ export class AuthorizationAttributesSnsService implements AuthorizationAttribute
|
|
|
41
40
|
this.entitySnsArn = AuthorizationAttributesSnsService.getSnsTopicArn(SnsTopicType.ENTITY);
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
/**
|
|
45
|
-
* Async function to upsert resource attributes using SNS.
|
|
46
|
-
* Sends the updates request to SNS and returns before the change actually took place.
|
|
47
|
-
* @param accountId The account ID
|
|
48
|
-
* @param appName App name of the calling app
|
|
49
|
-
* @param callerActionIdentifier Action identifier
|
|
50
|
-
* @param resourceAttributeAssignments Array of resource attribute assignments to upsert
|
|
51
|
-
* @return Promise with array of sent operations
|
|
52
|
-
*/
|
|
53
|
-
async upsertResourceAttributes(
|
|
54
|
-
accountId: number,
|
|
55
|
-
resourceAttributeAssignments: ResourceAttributeAssignment[],
|
|
56
|
-
appName?: string,
|
|
57
|
-
callerActionIdentifier?: string
|
|
58
|
-
): Promise<ResourceAttributeOperation[]> {
|
|
59
|
-
if (!appName || !callerActionIdentifier) {
|
|
60
|
-
throw new Error('appName and callerActionIdentifier are required for SNS service');
|
|
61
|
-
}
|
|
62
|
-
const operations: ResourceAttributeOperation[] = resourceAttributeAssignments.map(assignment => ({
|
|
63
|
-
...assignment,
|
|
64
|
-
operationType: AttributeOperation.UPSERT,
|
|
65
|
-
}));
|
|
66
|
-
return this.updateResourceAttributes(accountId, appName, callerActionIdentifier, operations);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
43
|
/**
|
|
70
44
|
* Async function to delete resource attributes using SNS.
|
|
71
45
|
* Sends the updates request to SNS and returns before the change actually took place.
|
|
@@ -90,7 +64,7 @@ export class AuthorizationAttributesSnsService implements AuthorizationAttribute
|
|
|
90
64
|
key =>
|
|
91
65
|
({
|
|
92
66
|
resourceType: resource.type,
|
|
93
|
-
resourceId: resource.id
|
|
67
|
+
resourceId: resource.id,
|
|
94
68
|
key,
|
|
95
69
|
operationType: AttributeOperation.DELETE,
|
|
96
70
|
} as ResourceAttributeOperation)
|
|
@@ -98,36 +72,6 @@ export class AuthorizationAttributesSnsService implements AuthorizationAttribute
|
|
|
98
72
|
return this.updateResourceAttributes(accountId, appName, callerActionIdentifier, operations);
|
|
99
73
|
}
|
|
100
74
|
|
|
101
|
-
/**
|
|
102
|
-
* Async function to upsert entity attributes using SNS.
|
|
103
|
-
* Sends the updates request to SNS and returns before the change actually took place.
|
|
104
|
-
* @param accountId The account ID
|
|
105
|
-
* @param appName App name of the calling app
|
|
106
|
-
* @param callerActionIdentifier Action identifier
|
|
107
|
-
* @param entityAttributeAssignments Array of entity attribute assignments to upsert
|
|
108
|
-
* @return Promise with array of sent operations
|
|
109
|
-
*/
|
|
110
|
-
async upsertEntityAttributes(
|
|
111
|
-
accountId: number,
|
|
112
|
-
entityAttributeAssignments: EntityAttributeAssignment[],
|
|
113
|
-
appName?: string,
|
|
114
|
-
callerActionIdentifier?: string
|
|
115
|
-
): Promise<EntityAttributeOperation[]> {
|
|
116
|
-
if (!appName || !callerActionIdentifier) {
|
|
117
|
-
throw new Error('appName and callerActionIdentifier are required for SNS service');
|
|
118
|
-
}
|
|
119
|
-
const operations: EntityAttributeOperation[] = entityAttributeAssignments.map(assignment => {
|
|
120
|
-
return {
|
|
121
|
-
entityId: assignment.entityId,
|
|
122
|
-
entityType: assignment.entityType,
|
|
123
|
-
key: assignment.attributeKey,
|
|
124
|
-
value: assignment.attributeValue,
|
|
125
|
-
operationType: AttributeOperation.UPSERT,
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
return this.updateEntityAttributes(accountId, appName, callerActionIdentifier, operations);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
75
|
/**
|
|
132
76
|
* Async function to delete entity attributes using SNS.
|
|
133
77
|
* Sends the updates request to SNS and returns before the change actually took place.
|
|
@@ -141,7 +85,7 @@ export class AuthorizationAttributesSnsService implements AuthorizationAttribute
|
|
|
141
85
|
*/
|
|
142
86
|
async deleteEntityAttributes(
|
|
143
87
|
accountId: number,
|
|
144
|
-
entityType: EntityType
|
|
88
|
+
entityType: EntityType,
|
|
145
89
|
entityId: number,
|
|
146
90
|
attributeKeys: string[],
|
|
147
91
|
appName?: string,
|
|
@@ -150,15 +94,16 @@ export class AuthorizationAttributesSnsService implements AuthorizationAttribute
|
|
|
150
94
|
if (!appName || !callerActionIdentifier) {
|
|
151
95
|
throw new Error('appName and callerActionIdentifier are required for SNS service');
|
|
152
96
|
}
|
|
153
|
-
const operations: EntityAttributeOperation[] = attributeKeys.map(
|
|
154
|
-
key
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
97
|
+
const operations: EntityAttributeOperation[] = attributeKeys.map(key => {
|
|
98
|
+
ValidationUtils.validateEntityAssignment({ entityId, entityType, key, value: '' });
|
|
99
|
+
return {
|
|
100
|
+
entityType: entityType,
|
|
101
|
+
entityId,
|
|
102
|
+
key,
|
|
103
|
+
operationType: AttributeOperation.DELETE,
|
|
104
|
+
value: '',
|
|
105
|
+
};
|
|
106
|
+
});
|
|
162
107
|
return this.updateEntityAttributes(accountId, appName, callerActionIdentifier, operations);
|
|
163
108
|
}
|
|
164
109
|
|
|
@@ -1,36 +1,20 @@
|
|
|
1
|
-
import { ValidationUtils } from './utils/validation';
|
|
2
1
|
import isEqual from 'lodash/isEqual.js';
|
|
3
|
-
import { EntityAttributeAssignment, ResourceAttributeDelete } from './types/authorization-attributes-contracts';
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Base class for attribute assignments (Resource or Entity)
|
|
7
5
|
* Provides common validation and functionality
|
|
8
6
|
*/
|
|
9
|
-
export abstract class BaseAttributeAssignment<
|
|
10
|
-
public readonly id:
|
|
11
|
-
public readonly type:
|
|
7
|
+
export abstract class BaseAttributeAssignment<T, R> {
|
|
8
|
+
public readonly id: number;
|
|
9
|
+
public readonly type: T;
|
|
12
10
|
public readonly attributeKey: string;
|
|
13
11
|
public readonly attributeValue: string;
|
|
14
12
|
|
|
15
|
-
constructor(
|
|
16
|
-
id
|
|
17
|
-
type
|
|
18
|
-
attributeKey
|
|
19
|
-
attributeValue
|
|
20
|
-
validTypes: readonly string[],
|
|
21
|
-
idFieldName: string,
|
|
22
|
-
typeFieldName: string
|
|
23
|
-
) {
|
|
24
|
-
const validated = ValidationUtils.validateAssignment<TType>(
|
|
25
|
-
{ id, type, attributeKey, attributeValue },
|
|
26
|
-
validTypes as readonly TType[],
|
|
27
|
-
{ id: idFieldName, type: typeFieldName }
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
this.id = validated.id as TId;
|
|
31
|
-
this.type = validated.type as TType;
|
|
32
|
-
this.attributeKey = validated.attributeKey;
|
|
33
|
-
this.attributeValue = validated.attributeValue;
|
|
13
|
+
constructor(id: number, type: T, attributeKey: string, attributeValue: string) {
|
|
14
|
+
this.id = id;
|
|
15
|
+
this.type = type;
|
|
16
|
+
this.attributeKey = attributeKey;
|
|
17
|
+
this.attributeValue = attributeValue;
|
|
34
18
|
}
|
|
35
19
|
|
|
36
20
|
/**
|
|
@@ -38,9 +22,9 @@ export abstract class BaseAttributeAssignment<TId extends number, TType extends
|
|
|
38
22
|
* @param other Another assignment instance
|
|
39
23
|
* @returns true if all properties are equal
|
|
40
24
|
*/
|
|
41
|
-
equals(other: BaseAttributeAssignment<
|
|
25
|
+
equals(other: BaseAttributeAssignment<T, R>): boolean {
|
|
42
26
|
return isEqual(this, other);
|
|
43
27
|
}
|
|
44
28
|
|
|
45
|
-
abstract toDataTransferObject():
|
|
29
|
+
abstract toDataTransferObject(): R;
|
|
46
30
|
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityType } from './entity-attributes-constants';
|
|
2
2
|
import { BaseAttributeAssignment } from './base-attribute-assignment';
|
|
3
|
+
import { EntityAttributeAssignment as EntityAttributeAssignmentContract } from './types/authorization-attributes-contracts';
|
|
4
|
+
import { ValidationUtils } from './utils/validation';
|
|
3
5
|
|
|
4
|
-
export class EntityAttributeAssignment extends BaseAttributeAssignment<
|
|
6
|
+
export class EntityAttributeAssignment extends BaseAttributeAssignment<EntityType, EntityAttributeAssignmentContract> {
|
|
5
7
|
public readonly entityId: number;
|
|
6
8
|
public readonly entityType: EntityType;
|
|
7
9
|
|
|
8
|
-
constructor(entityId: number, entityType:
|
|
9
|
-
|
|
10
|
+
constructor(entityId: number, entityType: EntityType, attributeKey: string, attributeValue: string) {
|
|
11
|
+
ValidationUtils.validateEntityAssignment({ entityId, entityType, key: attributeKey, value: attributeValue });
|
|
12
|
+
super(entityId, entityType, attributeKey, attributeValue);
|
|
10
13
|
this.entityId = entityId;
|
|
11
|
-
this.entityType =
|
|
14
|
+
this.entityType = entityType;
|
|
12
15
|
}
|
|
13
16
|
|
|
14
|
-
toDataTransferObject() {
|
|
17
|
+
toDataTransferObject(): EntityAttributeAssignmentContract {
|
|
15
18
|
return {
|
|
16
19
|
entityId: this.entityId,
|
|
17
20
|
entityType: this.entityType,
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ResourceType } from './resource-attributes-constants';
|
|
2
2
|
import { BaseAttributeAssignment } from './base-attribute-assignment';
|
|
3
|
+
import { ResourceAttributeAssignment as ResourceAttributeAssignmentContract } from './types/authorization-attributes-contracts';
|
|
4
|
+
import { ValidationUtils } from './utils/validation';
|
|
3
5
|
|
|
4
|
-
export class ResourceAttributeAssignment extends BaseAttributeAssignment<
|
|
6
|
+
export class ResourceAttributeAssignment extends BaseAttributeAssignment<
|
|
7
|
+
ResourceType,
|
|
8
|
+
ResourceAttributeAssignmentContract
|
|
9
|
+
> {
|
|
5
10
|
public readonly resourceId: number;
|
|
6
11
|
public readonly resourceType: ResourceType;
|
|
7
12
|
|
|
8
13
|
constructor(resourceId: number, resourceType: ResourceType, attributeKey: string, attributeValue: string) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
resourceType,
|
|
12
|
-
attributeKey,
|
|
13
|
-
attributeValue,
|
|
14
|
-
Object.values(RESOURCE_TYPES),
|
|
15
|
-
'resourceId',
|
|
16
|
-
'resourceType'
|
|
17
|
-
);
|
|
14
|
+
ValidationUtils.validateResourceAssignment({ resourceId, resourceType, key: attributeKey, value: attributeValue });
|
|
15
|
+
super(resourceId, resourceType, attributeKey, attributeValue);
|
|
18
16
|
this.resourceId = resourceId;
|
|
19
17
|
this.resourceType = this.type;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
toDataTransferObject() {
|
|
20
|
+
toDataTransferObject(): ResourceAttributeAssignmentContract {
|
|
23
21
|
return {
|
|
24
22
|
resourceId: this.resourceId,
|
|
25
23
|
resourceType: this.resourceType,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const RESOURCE_ATTRIBUTES_CONSTANTS = {
|
|
1
|
+
export const RESOURCE_ATTRIBUTES_CONSTANTS = Object.freeze({
|
|
2
2
|
ACCOUNT_RESOURCE_ATTRIBUTES: {
|
|
3
3
|
ENABLE_MEMBERS_INVITE_FROM_NON_AUTH_DOMAIN: 'enable_members_invite_from_non_auth_domain',
|
|
4
4
|
},
|
|
@@ -9,7 +9,7 @@ export const RESOURCE_ATTRIBUTES_CONSTANTS = {
|
|
|
9
9
|
IS_SYNCABLE_CHILD_ENTITY: 'is_syncable_child_entity',
|
|
10
10
|
SYSTEM_ENTITY_TYPE: 'system_entity_type',
|
|
11
11
|
},
|
|
12
|
-
}
|
|
12
|
+
});
|
|
13
13
|
|
|
14
14
|
export enum ResourceType {
|
|
15
15
|
Account = 'account',
|
package/src/testKit/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseRequest, BaseResponse, ContextGetter, Resource, ResourceGetter } from '../types/general';
|
|
1
|
+
import { Action, BaseRequest, BaseResponse, ContextGetter, Resource, ResourceGetter } from '../types/general';
|
|
2
2
|
import { defaultContextGetter } from '../authorization-middleware';
|
|
3
3
|
import { AuthorizationInternalService } from '../authorization-internal-service';
|
|
4
4
|
import type { NextFunction } from 'express';
|
|
@@ -7,11 +7,11 @@ export type TestPermittedAction = {
|
|
|
7
7
|
accountId: number;
|
|
8
8
|
userId: number;
|
|
9
9
|
resources: Resource[];
|
|
10
|
-
action:
|
|
10
|
+
action: Action;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
let testPermittedActions: TestPermittedAction[] = [];
|
|
14
|
-
export const addTestPermittedAction = (accountId: number, userId: number, resources: Resource[], action:
|
|
14
|
+
export const addTestPermittedAction = (accountId: number, userId: number, resources: Resource[], action: Action) => {
|
|
15
15
|
testPermittedActions.push({ accountId, userId, resources, action });
|
|
16
16
|
};
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@ export const clearTestPermittedActions = () => {
|
|
|
19
19
|
testPermittedActions = [];
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
const isActionAuthorized = (accountId: number, userId: number, resources: Resource[], action:
|
|
22
|
+
const isActionAuthorized = (accountId: number, userId: number, resources: Resource[], action: Action) => {
|
|
23
23
|
// If no resources to check, deny access
|
|
24
24
|
if (resources.length === 0) {
|
|
25
25
|
return { isAuthorized: false };
|
|
@@ -46,7 +46,7 @@ const isActionAuthorized = (accountId: number, userId: number, resources: Resour
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
export const getTestAuthorizationMiddleware = (
|
|
49
|
-
action:
|
|
49
|
+
action: Action,
|
|
50
50
|
resourceGetter: ResourceGetter,
|
|
51
51
|
contextGetter?: ContextGetter
|
|
52
52
|
) => {
|
|
@@ -2,7 +2,7 @@ import { Resource } from './general';
|
|
|
2
2
|
import type { EntityType } from '../entity-attributes-constants';
|
|
3
3
|
import type { ResourceType } from '../resource-attributes-constants';
|
|
4
4
|
|
|
5
|
-
interface AttributeAssignment {
|
|
5
|
+
export interface AttributeAssignment {
|
|
6
6
|
key: string;
|
|
7
7
|
value: string;
|
|
8
8
|
}
|