@mondaydotcomorg/monday-authorization 3.5.1-fix-authorize-profile-picker-7481de0 → 3.5.3-feat-shaime-support-entity-attributes-in-authorization-sdk-e355942
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 +95 -0
- package/dist/authorization-attributes-ms-service.d.ts.map +1 -0
- package/dist/authorization-attributes-ms-service.js +362 -0
- package/dist/authorization-attributes-service.d.ts +26 -47
- package/dist/authorization-attributes-service.d.ts.map +1 -1
- package/dist/authorization-attributes-service.js +33 -171
- package/dist/authorization-attributes-sns-service.d.ts +91 -0
- package/dist/authorization-attributes-sns-service.d.ts.map +1 -0
- package/dist/authorization-attributes-sns-service.js +217 -0
- package/dist/authorization-middleware.d.ts +2 -2
- package/dist/authorization-middleware.d.ts.map +1 -1
- package/dist/authorization-service.d.ts +3 -3
- package/dist/authorization-service.d.ts.map +1 -1
- package/dist/authorization-service.js +7 -34
- package/dist/base-attribute-assignment.d.ts +18 -0
- package/dist/base-attribute-assignment.d.ts.map +1 -0
- package/dist/base-attribute-assignment.js +43 -0
- package/dist/constants/sns.d.ts +12 -2
- package/dist/constants/sns.d.ts.map +1 -1
- package/dist/constants/sns.js +22 -2
- package/dist/entity-attribute-assignment.d.ts +14 -0
- package/dist/entity-attribute-assignment.d.ts.map +1 -0
- package/dist/entity-attribute-assignment.js +24 -0
- package/dist/entity-attributes-constants.d.ts +7 -0
- package/dist/entity-attributes-constants.d.ts.map +1 -0
- package/dist/entity-attributes-constants.js +9 -0
- package/dist/errors/argument-error.d.ts +4 -0
- package/dist/errors/argument-error.d.ts.map +1 -0
- package/dist/errors/argument-error.js +11 -0
- package/dist/esm/authorization-attributes-ms-service.d.ts +95 -0
- package/dist/esm/authorization-attributes-ms-service.d.ts.map +1 -0
- package/dist/esm/authorization-attributes-ms-service.mjs +360 -0
- package/dist/esm/authorization-attributes-service.d.ts +26 -47
- package/dist/esm/authorization-attributes-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-service.mjs +33 -167
- package/dist/esm/authorization-attributes-sns-service.d.ts +91 -0
- package/dist/esm/authorization-attributes-sns-service.d.ts.map +1 -0
- package/dist/esm/authorization-attributes-sns-service.mjs +211 -0
- package/dist/esm/authorization-middleware.d.ts +2 -2
- package/dist/esm/authorization-middleware.d.ts.map +1 -1
- package/dist/esm/authorization-service.d.ts +3 -3
- package/dist/esm/authorization-service.d.ts.map +1 -1
- package/dist/esm/authorization-service.mjs +7 -34
- package/dist/esm/base-attribute-assignment.d.ts +18 -0
- package/dist/esm/base-attribute-assignment.d.ts.map +1 -0
- package/dist/esm/base-attribute-assignment.mjs +41 -0
- package/dist/esm/constants/sns.d.ts +12 -2
- package/dist/esm/constants/sns.d.ts.map +1 -1
- package/dist/esm/constants/sns.mjs +17 -3
- package/dist/esm/entity-attribute-assignment.d.ts +14 -0
- package/dist/esm/entity-attribute-assignment.d.ts.map +1 -0
- package/dist/esm/entity-attribute-assignment.mjs +22 -0
- package/dist/esm/entity-attributes-constants.d.ts +7 -0
- package/dist/esm/entity-attributes-constants.d.ts.map +1 -0
- package/dist/esm/entity-attributes-constants.mjs +7 -0
- package/dist/esm/errors/argument-error.d.ts +4 -0
- package/dist/esm/errors/argument-error.d.ts.map +1 -0
- package/dist/esm/errors/argument-error.mjs +9 -0
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.mjs +7 -0
- package/dist/esm/prometheus-service.d.ts +1 -2
- package/dist/esm/prometheus-service.d.ts.map +1 -1
- package/dist/esm/resource-attribute-assignment.d.ts +24 -0
- package/dist/esm/resource-attribute-assignment.d.ts.map +1 -0
- package/dist/esm/resource-attribute-assignment.mjs +34 -0
- package/dist/esm/resource-attributes-constants.d.ts +15 -0
- package/dist/esm/resource-attributes-constants.d.ts.map +1 -0
- package/dist/esm/resource-attributes-constants.mjs +25 -0
- 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 +27 -12
- package/dist/esm/types/authorization-attributes-contracts.d.ts.map +1 -1
- package/dist/esm/types/authorization-attributes-contracts.mjs +6 -6
- package/dist/esm/types/authorization-attributes-service.interface.d.ts +57 -0
- package/dist/esm/types/authorization-attributes-service.interface.d.ts.map +1 -0
- package/dist/esm/types/authorization-attributes-service.interface.mjs +1 -0
- package/dist/esm/types/general.d.ts +1 -2
- package/dist/esm/types/general.d.ts.map +1 -1
- package/dist/esm/utils/validation.d.ts +45 -0
- package/dist/esm/utils/validation.d.ts.map +1 -0
- package/dist/esm/utils/validation.mjs +117 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/prometheus-service.d.ts +1 -2
- package/dist/prometheus-service.d.ts.map +1 -1
- package/dist/resource-attribute-assignment.d.ts +24 -0
- package/dist/resource-attribute-assignment.d.ts.map +1 -0
- package/dist/resource-attribute-assignment.js +36 -0
- package/dist/resource-attributes-constants.d.ts +15 -0
- package/dist/resource-attributes-constants.d.ts.map +1 -0
- package/dist/resource-attributes-constants.js +28 -0
- 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 +27 -12
- package/dist/types/authorization-attributes-contracts.d.ts.map +1 -1
- package/dist/types/authorization-attributes-contracts.js +5 -5
- package/dist/types/authorization-attributes-service.interface.d.ts +57 -0
- package/dist/types/authorization-attributes-service.interface.d.ts.map +1 -0
- package/dist/types/authorization-attributes-service.interface.js +1 -0
- package/dist/types/general.d.ts +1 -2
- package/dist/types/general.d.ts.map +1 -1
- package/dist/utils/validation.d.ts +45 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +119 -0
- package/package.json +3 -2
- package/src/authorization-attributes-ms-service.ts +528 -0
- package/src/authorization-attributes-service.ts +35 -222
- package/src/authorization-attributes-sns-service.ts +312 -0
- package/src/authorization-middleware.ts +2 -2
- package/src/authorization-service.ts +15 -75
- package/src/base-attribute-assignment.ts +55 -0
- package/src/constants/sns.ts +19 -2
- package/src/entity-attribute-assignment.ts +21 -0
- package/src/entity-attributes-constants.ts +7 -0
- package/src/errors/argument-error.ts +7 -0
- package/src/index.ts +9 -0
- package/src/prometheus-service.ts +1 -2
- package/src/resource-attribute-assignment.ts +43 -0
- package/src/resource-attributes-constants.ts +35 -0
- package/src/testKit/index.ts +5 -5
- package/src/types/authorization-attributes-contracts.ts +36 -11
- package/src/types/authorization-attributes-service.interface.ts +100 -0
- package/src/types/general.ts +3 -2
- package/src/utils/validation.ts +114 -0
|
@@ -3,7 +3,7 @@ import { MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
|
|
|
3
3
|
import { Api } from '@mondaydotcomorg/trident-backend-api';
|
|
4
4
|
import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
|
|
5
5
|
import { getIgniteClient, IgniteClient } from '@mondaydotcomorg/ignite-sdk';
|
|
6
|
-
import {
|
|
6
|
+
import { AuthorizationObject, AuthorizationParams, Resource } from './types/general';
|
|
7
7
|
import { sendAuthorizationCheckResponseTimeMetric } from './prometheus-service';
|
|
8
8
|
import { recordAuthorizationTiming } from './metrics-service';
|
|
9
9
|
import {
|
|
@@ -74,7 +74,7 @@ export class AuthorizationService {
|
|
|
74
74
|
accountId: number,
|
|
75
75
|
userId: number,
|
|
76
76
|
resources: Resource[],
|
|
77
|
-
action:
|
|
77
|
+
action: string
|
|
78
78
|
): Promise<AuthorizeResponse>;
|
|
79
79
|
|
|
80
80
|
static async isAuthorized(
|
|
@@ -155,60 +155,19 @@ export class AuthorizationService {
|
|
|
155
155
|
logger.error({ tag: 'authorization-service' }, 'AuthorizationService: igniteClient is not set, failing request');
|
|
156
156
|
throw new Error('AuthorizationService: igniteClient is not set, failing request');
|
|
157
157
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
);
|
|
163
|
-
const isAllowedProfile = allowedProfiles.includes(appName);
|
|
164
|
-
logger.error(
|
|
165
|
-
{ tag: 'auth-debug', accountId, userId, appName, allowedProfiles, isAllowedProfile },
|
|
166
|
-
'AuthorizationService.getProfile: checking allowed profiles'
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
if (isAllowedProfile) {
|
|
170
|
-
const profile = getProfile();
|
|
171
|
-
logger.error(
|
|
172
|
-
{ tag: 'auth-debug', accountId, userId, appName, profile },
|
|
173
|
-
'AuthorizationService.getProfile: selected profile via allowed profiles'
|
|
174
|
-
);
|
|
175
|
-
return profile;
|
|
158
|
+
if (
|
|
159
|
+
this.igniteClient.configuration.getObjectValue<string[]>(ALLOWED_SDK_PLATFORM_PROFILES_KEY, []).includes(appName)
|
|
160
|
+
) {
|
|
161
|
+
return getProfile();
|
|
176
162
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
logger.error(
|
|
186
|
-
{
|
|
187
|
-
tag: 'auth-debug',
|
|
188
|
-
accountId,
|
|
189
|
-
userId,
|
|
190
|
-
appName,
|
|
191
|
-
inReleaseProfiles,
|
|
192
|
-
isInReleaseProfile,
|
|
193
|
-
isFeatureFlagReleased,
|
|
194
|
-
featureFlag: PLATFORM_PROFILE_RELEASE_FF,
|
|
195
|
-
},
|
|
196
|
-
'AuthorizationService.getProfile: checking feature flag release'
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
if (isInReleaseProfile && isFeatureFlagReleased) {
|
|
200
|
-
const profile = getProfile();
|
|
201
|
-
logger.error(
|
|
202
|
-
{ tag: 'auth-debug', accountId, userId, appName, profile },
|
|
203
|
-
'AuthorizationService.getProfile: selected profile via feature flag release'
|
|
204
|
-
);
|
|
205
|
-
return profile;
|
|
163
|
+
if (
|
|
164
|
+
this.igniteClient.configuration
|
|
165
|
+
.getObjectValue<string[]>(IN_RELEASE_SDK_PLATFORM_PROFILES_KEY, [])
|
|
166
|
+
.includes(appName) &&
|
|
167
|
+
this.igniteClient.isReleased(PLATFORM_PROFILE_RELEASE_FF, { accountId, userId })
|
|
168
|
+
) {
|
|
169
|
+
return getProfile();
|
|
206
170
|
}
|
|
207
|
-
|
|
208
|
-
logger.error(
|
|
209
|
-
{ tag: 'auth-debug', accountId, userId, appName, profile: PlatformProfile.APP },
|
|
210
|
-
'AuthorizationService.getProfile: selected default APP profile'
|
|
211
|
-
);
|
|
212
171
|
return PlatformProfile.APP;
|
|
213
172
|
}
|
|
214
173
|
|
|
@@ -225,34 +184,15 @@ export class AuthorizationService {
|
|
|
225
184
|
this.igniteClient?.isReleased(NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF, { accountId, userId })
|
|
226
185
|
);
|
|
227
186
|
|
|
228
|
-
logger.error(
|
|
229
|
-
{
|
|
230
|
-
tag: 'auth-debug',
|
|
231
|
-
accountId,
|
|
232
|
-
userId,
|
|
233
|
-
shouldNavigateToGraph,
|
|
234
|
-
featureFlag: NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF,
|
|
235
|
-
},
|
|
236
|
-
'AuthorizationService.canActionInScopeMultiple: determining which API flow to use'
|
|
237
|
-
);
|
|
238
|
-
|
|
239
187
|
const startTime = performance.now();
|
|
240
188
|
let scopedActionResponseObjects: ScopedActionResponseObject[];
|
|
241
189
|
let apiType: 'graph' | 'platform';
|
|
242
190
|
|
|
243
191
|
if (shouldNavigateToGraph) {
|
|
244
192
|
apiType = 'graph';
|
|
245
|
-
logger.error(
|
|
246
|
-
{ tag: 'auth-debug', accountId, userId, apiType },
|
|
247
|
-
'AuthorizationService.canActionInScopeMultiple: using graph API flow'
|
|
248
|
-
);
|
|
249
193
|
scopedActionResponseObjects = await this.graphApi.checkPermissions(accountId, userId, scopedActions);
|
|
250
194
|
} else {
|
|
251
195
|
apiType = 'platform';
|
|
252
|
-
logger.error(
|
|
253
|
-
{ tag: 'auth-debug', accountId, userId, apiType },
|
|
254
|
-
'AuthorizationService.canActionInScopeMultiple: using platform API flow'
|
|
255
|
-
);
|
|
256
196
|
const profile = this.getProfile(accountId, userId);
|
|
257
197
|
const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
258
198
|
|
|
@@ -283,7 +223,7 @@ export class AuthorizationService {
|
|
|
283
223
|
accountId: number,
|
|
284
224
|
userId: number,
|
|
285
225
|
resources: Resource[],
|
|
286
|
-
action:
|
|
226
|
+
action: string
|
|
287
227
|
): Promise<AuthorizeResponse> {
|
|
288
228
|
const { authorizationObjects } = createAuthorizationParams(resources, action);
|
|
289
229
|
return this.isAuthorizedMultiple(accountId, userId, authorizationObjects);
|
|
@@ -398,7 +338,7 @@ export async function setIgniteClient() {
|
|
|
398
338
|
AuthorizationInternalService.setIgniteClient(igniteClient);
|
|
399
339
|
}
|
|
400
340
|
|
|
401
|
-
export function createAuthorizationParams(resources: Resource[], action:
|
|
341
|
+
export function createAuthorizationParams(resources: Resource[], action: string): AuthorizationParams {
|
|
402
342
|
const params = {
|
|
403
343
|
authorizationObjects: resources.map((resource: Resource) => {
|
|
404
344
|
const authorizationObject: AuthorizationObject = {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ValidationUtils } from './utils/validation';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base class for attribute assignments (Resource or Entity)
|
|
5
|
+
* Provides common validation and functionality
|
|
6
|
+
*/
|
|
7
|
+
export abstract class BaseAttributeAssignment<TId extends number, TType extends string> {
|
|
8
|
+
public readonly id: TId;
|
|
9
|
+
public readonly type: TType;
|
|
10
|
+
public readonly attributeKey: string;
|
|
11
|
+
public readonly attributeValue: string;
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
id: TId,
|
|
15
|
+
type: string,
|
|
16
|
+
attributeKey: string,
|
|
17
|
+
attributeValue: string,
|
|
18
|
+
validTypes: readonly string[],
|
|
19
|
+
idFieldName: string,
|
|
20
|
+
typeFieldName: string
|
|
21
|
+
) {
|
|
22
|
+
// Validate id
|
|
23
|
+
ValidationUtils.validateInteger(id, idFieldName);
|
|
24
|
+
|
|
25
|
+
// Validate type
|
|
26
|
+
this.type = ValidationUtils.validateEnum(type, validTypes as readonly TType[], typeFieldName) as TType;
|
|
27
|
+
|
|
28
|
+
// Validate attributeKey
|
|
29
|
+
ValidationUtils.validateString(attributeKey, 'attributeKey');
|
|
30
|
+
|
|
31
|
+
// Validate attributeValue
|
|
32
|
+
ValidationUtils.validateString(attributeValue, 'attributeValue');
|
|
33
|
+
|
|
34
|
+
this.id = id;
|
|
35
|
+
this.attributeKey = attributeKey;
|
|
36
|
+
this.attributeValue = attributeValue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Compares two assignments for equality
|
|
41
|
+
* @param other Another assignment instance
|
|
42
|
+
* @returns true if all properties are equal
|
|
43
|
+
*/
|
|
44
|
+
equals(other: BaseAttributeAssignment<TId, TType>): boolean {
|
|
45
|
+
if (!(other instanceof this.constructor)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return (
|
|
49
|
+
this.id === other.id &&
|
|
50
|
+
this.type === other.type &&
|
|
51
|
+
this.attributeKey === other.attributeKey &&
|
|
52
|
+
this.attributeValue === other.attributeValue
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/constants/sns.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export enum SnsTopicType {
|
|
2
|
+
RESOURCE = 'resource',
|
|
3
|
+
ENTITY = 'entity',
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// Resource SNS constants
|
|
7
|
+
export const RESOURCE_SNS_ARN_ENV_VAR_NAME = 'SHARED_AUTHORIZATION_SNS_ENDPOINT_RESOURCE_ATTRIBUTES';
|
|
8
|
+
export const RESOURCE_SNS_DEV_TEST_NAME =
|
|
3
9
|
'arn:aws:sns:us-east-1:000000000000:monday-authorization-resource-attributes-sns-local';
|
|
10
|
+
|
|
11
|
+
// Entity SNS constants
|
|
12
|
+
export const ENTITY_SNS_ARN_ENV_VAR_NAME = 'SHARED_AUTHORIZATION_SNS_ENDPOINT_ENTITY_ATTRIBUTES';
|
|
13
|
+
export const ENTITY_SNS_DEV_TEST_NAME =
|
|
14
|
+
'arn:aws:sns:us-east-1:000000000000:monday-authorization-entity-attributes-sns-local';
|
|
4
15
|
export const RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND = 'resourceAttributeModification';
|
|
16
|
+
export const ENTITY_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND = 'entityAttributeModification';
|
|
5
17
|
export const ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE = 100;
|
|
18
|
+
export const ASYNC_ENTITY_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE = 100;
|
|
19
|
+
|
|
20
|
+
// Legacy exports for backward compatibility
|
|
21
|
+
export const SNS_ARN_ENV_VAR_NAME = RESOURCE_SNS_ARN_ENV_VAR_NAME;
|
|
22
|
+
export const SNS_DEV_TEST_NAME = RESOURCE_SNS_DEV_TEST_NAME;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ENTITY_TYPES, EntityType } from './entity-attributes-constants';
|
|
2
|
+
import { BaseAttributeAssignment } from './base-attribute-assignment';
|
|
3
|
+
|
|
4
|
+
export class EntityAttributeAssignment extends BaseAttributeAssignment<number, EntityType> {
|
|
5
|
+
public readonly entityId: number;
|
|
6
|
+
public readonly entityType: EntityType;
|
|
7
|
+
|
|
8
|
+
constructor(entityId: number, entityType: string, attributeKey: string, attributeValue: string) {
|
|
9
|
+
super(entityId, entityType, attributeKey, attributeValue, Object.values(ENTITY_TYPES), 'entityId', 'entityType');
|
|
10
|
+
this.entityId = entityId;
|
|
11
|
+
this.entityType = this.type;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compares two assignments for equality
|
|
15
|
+
* @param other Another EntityAttributeAssignment instance
|
|
16
|
+
* @returns true if all properties are equal
|
|
17
|
+
*/
|
|
18
|
+
equals(other: EntityAttributeAssignment): boolean {
|
|
19
|
+
return super.equals(other);
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -58,6 +58,15 @@ export {
|
|
|
58
58
|
} from './authorization-middleware';
|
|
59
59
|
export { AuthorizationService, AuthorizeResponse } from './authorization-service';
|
|
60
60
|
export { AuthorizationAttributesService } from './authorization-attributes-service';
|
|
61
|
+
export { AuthorizationAttributesSnsService } from './authorization-attributes-sns-service';
|
|
62
|
+
export { AuthorizationAttributesMsService } from './authorization-attributes-ms-service';
|
|
63
|
+
export { IAuthorizationAttributesService } from './types/authorization-attributes-service.interface';
|
|
64
|
+
export { ResourceAttributeAssignment } from './resource-attribute-assignment';
|
|
65
|
+
export { RESOURCE_TYPES, RESOURCE_ATTRIBUTES_CONSTANTS } from './resource-attributes-constants';
|
|
66
|
+
export { EntityAttributeAssignment } from './entity-attribute-assignment';
|
|
67
|
+
export { ENTITY_TYPES } from './entity-attributes-constants';
|
|
68
|
+
export { ArgumentError } from './errors/argument-error';
|
|
69
|
+
export type { EntityType } from './entity-attributes-constants';
|
|
61
70
|
export { RolesService } from './roles-service';
|
|
62
71
|
export { MembershipsService } from './memberships';
|
|
63
72
|
export { AuthorizationObject, Resource, BaseRequest, ResourceGetter, ContextGetter } from './types/general';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Action } from './types/general';
|
|
2
1
|
|
|
3
2
|
let prometheus: any = null;
|
|
4
3
|
let authorizationCheckResponseTimeMetric: any = null;
|
|
@@ -36,7 +35,7 @@ export function getMetricsManager() {
|
|
|
36
35
|
|
|
37
36
|
export function sendAuthorizationCheckResponseTimeMetric(
|
|
38
37
|
resourceType: string,
|
|
39
|
-
action:
|
|
38
|
+
action: string,
|
|
40
39
|
isAuthorized: boolean,
|
|
41
40
|
responseStatus: number,
|
|
42
41
|
time: number
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { RESOURCE_TYPES, ResourceType } from './resource-attributes-constants';
|
|
2
|
+
import { BaseAttributeAssignment } from './base-attribute-assignment';
|
|
3
|
+
|
|
4
|
+
export class ResourceAttributeAssignment extends BaseAttributeAssignment<number, ResourceType> {
|
|
5
|
+
public readonly resourceId: number;
|
|
6
|
+
public readonly resourceType: ResourceType;
|
|
7
|
+
|
|
8
|
+
constructor(resourceId: number, resourceType: string, attributeKey: string, attributeValue: string) {
|
|
9
|
+
super(
|
|
10
|
+
resourceId,
|
|
11
|
+
resourceType,
|
|
12
|
+
attributeKey,
|
|
13
|
+
attributeValue,
|
|
14
|
+
Object.values(RESOURCE_TYPES),
|
|
15
|
+
'resourceId',
|
|
16
|
+
'resourceType'
|
|
17
|
+
);
|
|
18
|
+
this.resourceId = resourceId;
|
|
19
|
+
this.resourceType = this.type;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Converts the assignment to a plain object with camelCase keys
|
|
24
|
+
* @returns Plain object with camelCase keys: { resourceId, resourceType, key, value }
|
|
25
|
+
*/
|
|
26
|
+
toPlainObject(): { resourceId: number; resourceType: string; key: string; value: string } {
|
|
27
|
+
return {
|
|
28
|
+
resourceId: this.resourceId,
|
|
29
|
+
resourceType: this.resourceType,
|
|
30
|
+
key: this.attributeKey,
|
|
31
|
+
value: this.attributeValue,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Compares two assignments for equality
|
|
37
|
+
* @param other Another ResourceAttributeAssignment instance
|
|
38
|
+
* @returns true if all properties are equal
|
|
39
|
+
*/
|
|
40
|
+
equals(other: ResourceAttributeAssignment): boolean {
|
|
41
|
+
return super.equals(other);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const RESOURCE_TYPES = {
|
|
2
|
+
ACCOUNT: 'account',
|
|
3
|
+
ACCOUNT_PRODUCT: 'account_product',
|
|
4
|
+
WORKSPACE: 'workspace',
|
|
5
|
+
BOARD: 'board',
|
|
6
|
+
ITEM: 'item',
|
|
7
|
+
TEAM: 'team',
|
|
8
|
+
OVERVIEW: 'overview',
|
|
9
|
+
DOCUMENT: 'document',
|
|
10
|
+
CRM: 'crm',
|
|
11
|
+
} as Record<string, ResourceType>;
|
|
12
|
+
|
|
13
|
+
export const RESOURCE_ATTRIBUTES_CONSTANTS = {
|
|
14
|
+
ACCOUNT_RESOURCE_ATTRIBUTES: {
|
|
15
|
+
ENABLE_MEMBERS_INVITE_FROM_NON_AUTH_DOMAIN: 'enable_members_invite_from_non_auth_domain',
|
|
16
|
+
},
|
|
17
|
+
WORKSPACE_RESOURCE_ATTRIBUTES: {
|
|
18
|
+
IS_DEFAULT_WORKSPACE: 'is_default_workspace',
|
|
19
|
+
},
|
|
20
|
+
BOARD_RESOURCE_ATTRIBUTES: {
|
|
21
|
+
IS_SYNCABLE_CHILD_ENTITY: 'is_syncable_child_entity',
|
|
22
|
+
SYSTEM_ENTITY_TYPE: 'system_entity_type',
|
|
23
|
+
},
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
export type ResourceType =
|
|
27
|
+
| 'account'
|
|
28
|
+
| 'account_product'
|
|
29
|
+
| 'workspace'
|
|
30
|
+
| 'board'
|
|
31
|
+
| 'item'
|
|
32
|
+
| 'team'
|
|
33
|
+
| 'overview'
|
|
34
|
+
| 'document'
|
|
35
|
+
| 'crm';
|
package/src/testKit/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { 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: string;
|
|
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: string) => {
|
|
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: string) => {
|
|
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: string,
|
|
50
50
|
resourceGetter: ResourceGetter,
|
|
51
51
|
contextGetter?: ContextGetter
|
|
52
52
|
) => {
|
|
@@ -1,33 +1,58 @@
|
|
|
1
1
|
import { Resource } from './general';
|
|
2
|
+
import type { EntityType } from '../entity-attributes-constants';
|
|
3
|
+
import type { ResourceType } from '../resource-attributes-constants';
|
|
2
4
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
export type { EntityType, ResourceType };
|
|
6
|
+
|
|
7
|
+
interface AttributeAssignment {
|
|
6
8
|
key: string;
|
|
7
9
|
value: string;
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
// Resource Attribute Assignment - matching API contract
|
|
13
|
+
export interface ResourceAttributeAssignment extends AttributeAssignment {
|
|
14
|
+
resourceId: number;
|
|
15
|
+
resourceType: ResourceType;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Entity Attribute Assignment - matching API contract
|
|
19
|
+
// Note: For validation, use the EntityAttributeAssignment class from '../entity-attribute-assignment'
|
|
20
|
+
export interface EntityAttributeAssignment extends AttributeAssignment {
|
|
21
|
+
entityId: number;
|
|
22
|
+
entityType: EntityType;
|
|
12
23
|
}
|
|
13
24
|
|
|
25
|
+
// Legacy types for backward compatibility
|
|
14
26
|
export interface ResourceAttributeDelete {
|
|
15
27
|
resourceType: Resource['type'];
|
|
16
28
|
resourceId: Resource['id'];
|
|
17
29
|
key: string;
|
|
18
30
|
}
|
|
19
31
|
|
|
20
|
-
export
|
|
32
|
+
export interface EntityAttributeDelete {
|
|
33
|
+
entityType: EntityType;
|
|
34
|
+
entityId: number;
|
|
35
|
+
key: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export enum AttributeOperation {
|
|
21
39
|
UPSERT = 'upsert',
|
|
22
40
|
DELETE = 'delete',
|
|
23
41
|
}
|
|
24
42
|
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
// Response types
|
|
44
|
+
export interface ResourceAttributeResponse {
|
|
45
|
+
attributes: ResourceAttributeAssignment[];
|
|
27
46
|
}
|
|
28
47
|
|
|
29
|
-
interface
|
|
30
|
-
|
|
48
|
+
export interface EntityAttributeResponse {
|
|
49
|
+
attributes: EntityAttributeAssignment[];
|
|
31
50
|
}
|
|
32
51
|
|
|
33
|
-
export
|
|
52
|
+
export interface ResourceAttributeOperation extends ResourceAttributeAssignment {
|
|
53
|
+
operationType: AttributeOperation;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface EntityAttributeOperation extends EntityAttributeAssignment {
|
|
57
|
+
operationType: AttributeOperation;
|
|
58
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ResourceAttributeAssignment as ResourceAttributeAssignmentContract,
|
|
3
|
+
EntityAttributeAssignment as EntityAttributeAssignmentContract,
|
|
4
|
+
EntityType,
|
|
5
|
+
} from './authorization-attributes-contracts';
|
|
6
|
+
import { ResourceAttributeOperation, EntityAttributeOperation } from './authorization-attributes-contracts';
|
|
7
|
+
import { ResourceAttributeAssignment } from '../resource-attribute-assignment';
|
|
8
|
+
import { EntityAttributeAssignment } from '../entity-attribute-assignment';
|
|
9
|
+
import { Resource } from './general';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Resource type compatible with both MS and SNS services
|
|
13
|
+
*/
|
|
14
|
+
export interface CompatibleResource {
|
|
15
|
+
resourceType?: string;
|
|
16
|
+
resourceId?: number;
|
|
17
|
+
type?: string;
|
|
18
|
+
id?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Interface for authorization attributes operations.
|
|
23
|
+
* Both MS (direct) and SNS (async) services implement this interface.
|
|
24
|
+
*/
|
|
25
|
+
export interface IAuthorizationAttributesService {
|
|
26
|
+
/**
|
|
27
|
+
* Upserts resource attributes.
|
|
28
|
+
* For MS service: returns Promise<void>
|
|
29
|
+
* For SNS service: requires appName and callerActionIdentifier, returns Promise<ResourceAttributesOperation[]>
|
|
30
|
+
*/
|
|
31
|
+
upsertResourceAttributes(
|
|
32
|
+
accountId: number,
|
|
33
|
+
resourceAttributeAssignments: ResourceAttributeAssignment[] | ResourceAttributeAssignmentContract[],
|
|
34
|
+
appName?: string,
|
|
35
|
+
callerActionIdentifier?: string
|
|
36
|
+
): Promise<void | ResourceAttributeOperation[]>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Deletes resource attributes.
|
|
40
|
+
* For MS service: returns Promise<void>
|
|
41
|
+
* For SNS service: requires appName and callerActionIdentifier, returns Promise<ResourceAttributesOperation[]>
|
|
42
|
+
*/
|
|
43
|
+
deleteResourceAttributes(
|
|
44
|
+
accountId: number,
|
|
45
|
+
resource: CompatibleResource | Resource,
|
|
46
|
+
attributeKeys: string[],
|
|
47
|
+
appName?: string,
|
|
48
|
+
callerActionIdentifier?: string
|
|
49
|
+
): Promise<void | ResourceAttributeOperation[]>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Upserts entity attributes.
|
|
53
|
+
* For MS service: returns Promise<void>
|
|
54
|
+
* For SNS service: requires appName and callerActionIdentifier, returns Promise<EntityAttributesOperation[]>
|
|
55
|
+
*/
|
|
56
|
+
upsertEntityAttributes(
|
|
57
|
+
accountId: number,
|
|
58
|
+
entityAttributeAssignments: EntityAttributeAssignment[] | EntityAttributeAssignmentContract[],
|
|
59
|
+
appName?: string,
|
|
60
|
+
callerActionIdentifier?: string
|
|
61
|
+
): Promise<void | EntityAttributeOperation[]>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Deletes entity attributes.
|
|
65
|
+
* For MS service: returns Promise<void>
|
|
66
|
+
* For SNS service: requires appName and callerActionIdentifier, returns Promise<EntityAttributesOperation[]>
|
|
67
|
+
*/
|
|
68
|
+
deleteEntityAttributes(
|
|
69
|
+
accountId: number,
|
|
70
|
+
entityType: EntityType | string,
|
|
71
|
+
entityId: number,
|
|
72
|
+
attributeKeys: string[],
|
|
73
|
+
appName?: string,
|
|
74
|
+
callerActionIdentifier?: string
|
|
75
|
+
): Promise<void | EntityAttributeOperation[]>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Updates resource attributes (batch operations).
|
|
79
|
+
* For MS service: may throw error or delegate to upsert/delete
|
|
80
|
+
* For SNS service: returns Promise<ResourceAttributesOperation[]>
|
|
81
|
+
*/
|
|
82
|
+
updateResourceAttributes(
|
|
83
|
+
accountId: number,
|
|
84
|
+
appName: string,
|
|
85
|
+
callerActionIdentifier: string,
|
|
86
|
+
resourceAttributeOperations: ResourceAttributeOperation[]
|
|
87
|
+
): Promise<ResourceAttributeOperation[]>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Updates entity attributes (batch operations).
|
|
91
|
+
* For MS service: may throw error or delegate to upsert/delete
|
|
92
|
+
* For SNS service: returns Promise<EntityAttributesOperation[]>
|
|
93
|
+
*/
|
|
94
|
+
updateEntityAttributes(
|
|
95
|
+
accountId: number,
|
|
96
|
+
appName: string,
|
|
97
|
+
callerActionIdentifier: string,
|
|
98
|
+
entityAttributeOperations: EntityAttributeOperation[]
|
|
99
|
+
): Promise<EntityAttributeOperation[]>;
|
|
100
|
+
}
|
package/src/types/general.ts
CHANGED
|
@@ -5,16 +5,17 @@ export interface Resource {
|
|
|
5
5
|
type: string;
|
|
6
6
|
wrapperData?: object;
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
export interface Context {
|
|
10
10
|
accountId: number;
|
|
11
11
|
userId: number;
|
|
12
12
|
}
|
|
13
|
+
|
|
13
14
|
export interface AuthorizationObject {
|
|
14
15
|
resource_id?: Resource['id'];
|
|
15
16
|
resource_type: Resource['type'];
|
|
16
17
|
wrapper_data?: Resource['wrapperData'];
|
|
17
|
-
action:
|
|
18
|
+
action: string;
|
|
18
19
|
}
|
|
19
20
|
export interface AuthorizationParams {
|
|
20
21
|
authorizationObjects: AuthorizationObject[];
|