@mondaydotcomorg/monday-authorization 3.5.3-feat-shaime-support-entity-attributes-in-authorization-sdk-a77c130 → 3.7.0-feat-shaime-support-entity-attributes-4-49e1de0
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 +6 -8
- package/dist/authorization-attributes-ms-service.d.ts.map +1 -1
- package/dist/authorization-attributes-ms-service.js +13 -75
- package/dist/authorization-attributes-service.d.ts +1 -2
- package/dist/authorization-attributes-service.d.ts.map +1 -1
- package/dist/authorization-attributes-service.js +0 -1
- package/dist/authorization-attributes-sns-service.d.ts +4 -3
- package/dist/authorization-attributes-sns-service.d.ts.map +1 -1
- 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/base-attribute-assignment.d.ts +2 -0
- package/dist/base-attribute-assignment.d.ts.map +1 -1
- package/dist/base-attribute-assignment.js +11 -18
- package/dist/entity-attribute-assignment.js +1 -1
- package/dist/entity-attributes-constants.d.ts +6 -6
- package/dist/entity-attributes-constants.d.ts.map +1 -1
- package/dist/entity-attributes-constants.js +7 -5
- 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 +6 -8
- package/dist/esm/authorization-attributes-ms-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-ms-service.mjs +13 -75
- package/dist/esm/authorization-attributes-service.d.ts +1 -2
- package/dist/esm/authorization-attributes-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-service.mjs +0 -1
- package/dist/esm/authorization-attributes-sns-service.d.ts +4 -3
- package/dist/esm/authorization-attributes-sns-service.d.ts.map +1 -1
- 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/base-attribute-assignment.d.ts +2 -0
- package/dist/esm/base-attribute-assignment.d.ts.map +1 -1
- package/dist/esm/base-attribute-assignment.mjs +7 -18
- package/dist/esm/entity-attribute-assignment.mjs +1 -1
- package/dist/esm/entity-attributes-constants.d.ts +6 -6
- package/dist/esm/entity-attributes-constants.d.ts.map +1 -1
- package/dist/esm/entity-attributes-constants.mjs +8 -6
- package/dist/esm/errors/argument-error.d.ts.map +1 -1
- package/dist/esm/errors/argument-error.mjs +0 -1
- package/dist/esm/index.d.ts +0 -9
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.mjs +0 -7
- package/dist/esm/prometheus-service.d.ts +2 -1
- package/dist/esm/prometheus-service.d.ts.map +1 -1
- package/dist/esm/resource-attribute-assignment.d.ts +1 -1
- package/dist/esm/resource-attribute-assignment.d.ts.map +1 -1
- package/dist/esm/resource-attributes-constants.d.ts +12 -2
- package/dist/esm/resource-attributes-constants.d.ts.map +1 -1
- package/dist/esm/resource-attributes-constants.mjs +15 -12
- package/dist/esm/types/authorization-attributes-contracts.d.ts +1 -1
- package/dist/esm/types/authorization-attributes-contracts.d.ts.map +1 -1
- package/dist/esm/types/authorization-attributes-service.interface.d.ts +4 -3
- package/dist/esm/types/authorization-attributes-service.interface.d.ts.map +1 -1
- package/dist/esm/types/general.d.ts +2 -1
- package/dist/esm/types/general.d.ts.map +1 -1
- package/dist/esm/utils/validation.d.ts +30 -30
- package/dist/esm/utils/validation.d.ts.map +1 -1
- package/dist/esm/utils/validation.mjs +121 -86
- package/dist/index.d.ts +0 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -15
- package/dist/prometheus-service.d.ts +2 -1
- package/dist/prometheus-service.d.ts.map +1 -1
- package/dist/resource-attribute-assignment.d.ts +1 -1
- package/dist/resource-attribute-assignment.d.ts.map +1 -1
- package/dist/resource-attributes-constants.d.ts +12 -2
- package/dist/resource-attributes-constants.d.ts.map +1 -1
- package/dist/resource-attributes-constants.js +14 -11
- package/dist/types/authorization-attributes-contracts.d.ts +1 -1
- package/dist/types/authorization-attributes-contracts.d.ts.map +1 -1
- package/dist/types/authorization-attributes-service.interface.d.ts +4 -3
- package/dist/types/authorization-attributes-service.interface.d.ts.map +1 -1
- package/dist/types/general.d.ts +2 -1
- package/dist/types/general.d.ts.map +1 -1
- package/dist/utils/validation.d.ts +30 -30
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +125 -86
- package/package.json +4 -3
- package/src/authorization-attributes-ms-service.ts +20 -97
- package/src/authorization-attributes-service.ts +1 -2
- package/src/authorization-attributes-sns-service.ts +3 -3
- package/src/authorization-middleware.ts +2 -2
- package/src/authorization-service.ts +4 -4
- package/src/base-attribute-assignment.ts +14 -23
- package/src/entity-attribute-assignment.ts +1 -1
- package/src/entity-attributes-constants.ts +6 -6
- package/src/errors/argument-error.ts +0 -1
- package/src/index.ts +0 -9
- package/src/prometheus-service.ts +3 -1
- package/src/resource-attribute-assignment.ts +1 -1
- package/src/resource-attributes-constants.ts +13 -21
- package/src/types/authorization-attributes-contracts.ts +0 -2
- package/src/types/authorization-attributes-service.interface.ts +3 -3
- package/src/types/general.ts +2 -3
- package/src/utils/validation.ts +139 -82
|
@@ -1,45 +1,45 @@
|
|
|
1
|
+
import { Resource } from '../types/general';
|
|
1
2
|
/**
|
|
2
|
-
* Utility class for common validation operations using
|
|
3
|
+
* Utility class for common validation operations using AJV
|
|
3
4
|
*/
|
|
4
5
|
export declare class ValidationUtils {
|
|
6
|
+
private static ajv;
|
|
5
7
|
/**
|
|
6
|
-
* Validates that a value is an integer
|
|
7
|
-
* @param value The value to validate
|
|
8
|
-
* @param fieldName The name of the field for error messages
|
|
9
|
-
* @throws ArgumentError if value is not an integer
|
|
8
|
+
* Validates that a value is an integer. Throws ArgumentError with a descriptive message on failure.
|
|
10
9
|
*/
|
|
11
|
-
static validateInteger(value:
|
|
10
|
+
static validateInteger(value: number): void;
|
|
12
11
|
/**
|
|
13
|
-
* Validates that a value is a non-empty string
|
|
14
|
-
* @param value The value to validate
|
|
15
|
-
* @param fieldName The name of the field for error messages
|
|
16
|
-
* @throws ArgumentError if value is not a string or is empty
|
|
12
|
+
* Validates that a value is a non-empty string. Throws ArgumentError on failure.
|
|
17
13
|
*/
|
|
18
|
-
static validateString(value:
|
|
14
|
+
static validateString(value: string): void;
|
|
19
15
|
/**
|
|
20
|
-
* Validates that a value is an array
|
|
21
|
-
*
|
|
22
|
-
* @param fieldName The name of the field for error messages
|
|
23
|
-
* @param minLength Minimum required length (default: 0)
|
|
24
|
-
* @returns The validated array
|
|
25
|
-
* @throws ArgumentError if value is not an array or doesn't meet minimum length
|
|
16
|
+
* Validates that a value is an array of non-empty strings. Throws ArgumentError on failure.
|
|
17
|
+
* Allows empty arrays - caller should handle early return.
|
|
26
18
|
*/
|
|
27
|
-
static
|
|
19
|
+
static validateStringArray(value: string[]): void;
|
|
28
20
|
/**
|
|
29
|
-
* Validates
|
|
30
|
-
*
|
|
31
|
-
* @param validValues Array of valid values
|
|
32
|
-
* @param fieldName The name of the field for error messages
|
|
33
|
-
* @returns The validated value as the enum type
|
|
34
|
-
* @throws ArgumentError if value is not in validValues
|
|
21
|
+
* Validates an attribute assignment object using a single AJV schema.
|
|
22
|
+
* Preserves legacy error messages for each field.
|
|
35
23
|
*/
|
|
36
|
-
static
|
|
24
|
+
static validateAssignment<TType extends string>(data: {
|
|
25
|
+
id: any;
|
|
26
|
+
type: string;
|
|
27
|
+
attributeKey: any;
|
|
28
|
+
attributeValue: any;
|
|
29
|
+
}, validTypes: readonly TType[], fieldNames: {
|
|
30
|
+
id: string;
|
|
31
|
+
type: string;
|
|
32
|
+
}): {
|
|
33
|
+
id: number;
|
|
34
|
+
type: TType;
|
|
35
|
+
attributeKey: string;
|
|
36
|
+
attributeValue: string;
|
|
37
|
+
};
|
|
37
38
|
/**
|
|
38
|
-
* Validates
|
|
39
|
-
*
|
|
40
|
-
* @param fieldName The name of the field for error messages
|
|
41
|
-
* @throws ArgumentError if any item is not a string
|
|
39
|
+
* Validates a Resource-like object shape: { id: number; type: string }.
|
|
40
|
+
* Throws ArgumentError with legacy-compatible messages.
|
|
42
41
|
*/
|
|
43
|
-
static
|
|
42
|
+
static validateResource(resource: Resource): void;
|
|
43
|
+
static validateArrayTypeOf<T>(attributesMessages: T[], messageClass: abstract new (...args: any[]) => T): void;
|
|
44
44
|
}
|
|
45
45
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAgC;IAClD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS3C;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAa1C;;;OAGG;IACH,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAkBjD;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAK,SAAS,MAAM,EAC5C,IAAI,EAAE;QAAE,EAAE,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,GAAG,CAAC;QAAC,cAAc,EAAE,GAAG,CAAA;KAAE,EACvE,UAAU,EAAE,SAAS,KAAK,EAAE,EAC5B,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GACvC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IA0D5E;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAqBjD,MAAM,CAAC,mBAAmB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI;CAoB/G"}
|
package/dist/utils/validation.js
CHANGED
|
@@ -1,117 +1,156 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const Ajv = require('ajv');
|
|
4
4
|
const errors_argumentError = require('../errors/argument-error.js');
|
|
5
5
|
|
|
6
|
+
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
7
|
+
|
|
8
|
+
const Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
|
|
9
|
+
|
|
6
10
|
/**
|
|
7
|
-
* Utility class for common validation operations using
|
|
11
|
+
* Utility class for common validation operations using AJV
|
|
8
12
|
*/
|
|
9
13
|
class ValidationUtils {
|
|
14
|
+
static ajv = new Ajv__default.default({ allErrors: true });
|
|
10
15
|
/**
|
|
11
|
-
* Validates that a value is an integer
|
|
12
|
-
* @param value The value to validate
|
|
13
|
-
* @param fieldName The name of the field for error messages
|
|
14
|
-
* @throws ArgumentError if value is not an integer
|
|
16
|
+
* Validates that a value is an integer. Throws ArgumentError with a descriptive message on failure.
|
|
15
17
|
*/
|
|
16
|
-
static validateInteger(value
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (error instanceof zod.z.ZodError) {
|
|
23
|
-
throw new errors_argumentError.ArgumentError(`${fieldName} must be an integer, got: ${value}`);
|
|
24
|
-
}
|
|
25
|
-
throw error;
|
|
18
|
+
static validateInteger(value) {
|
|
19
|
+
const numberSchema = { type: 'number', multipleOf: 1 };
|
|
20
|
+
const validate = ValidationUtils.ajv.compile(numberSchema);
|
|
21
|
+
const isValid = validate(value);
|
|
22
|
+
if (!isValid) {
|
|
23
|
+
throw new errors_argumentError.ArgumentError(`Value must be an integer, got: ${value}`);
|
|
26
24
|
}
|
|
27
25
|
}
|
|
28
26
|
/**
|
|
29
|
-
* Validates that a value is a non-empty string
|
|
30
|
-
* @param value The value to validate
|
|
31
|
-
* @param fieldName The name of the field for error messages
|
|
32
|
-
* @throws ArgumentError if value is not a string or is empty
|
|
27
|
+
* Validates that a value is a non-empty string. Throws ArgumentError on failure.
|
|
33
28
|
*/
|
|
34
|
-
static validateString(value
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
throw new errors_argumentError.ArgumentError(`${fieldName} must be a non-empty string`);
|
|
45
|
-
}
|
|
46
|
-
throw error;
|
|
29
|
+
static validateString(value) {
|
|
30
|
+
const non_empty_string_schema = {
|
|
31
|
+
type: 'string',
|
|
32
|
+
minLength: 1,
|
|
33
|
+
pattern: '\\S',
|
|
34
|
+
};
|
|
35
|
+
const validate = ValidationUtils.ajv.compile(non_empty_string_schema);
|
|
36
|
+
const isValid = validate(value);
|
|
37
|
+
if (!isValid) {
|
|
38
|
+
throw new errors_argumentError.ArgumentError(`Value must be a non-empty string, got: ${value}`);
|
|
47
39
|
}
|
|
48
40
|
}
|
|
49
41
|
/**
|
|
50
|
-
* Validates that a value is an array
|
|
51
|
-
*
|
|
52
|
-
* @param fieldName The name of the field for error messages
|
|
53
|
-
* @param minLength Minimum required length (default: 0)
|
|
54
|
-
* @returns The validated array
|
|
55
|
-
* @throws ArgumentError if value is not an array or doesn't meet minimum length
|
|
42
|
+
* Validates that a value is an array of non-empty strings. Throws ArgumentError on failure.
|
|
43
|
+
* Allows empty arrays - caller should handle early return.
|
|
56
44
|
*/
|
|
57
|
-
static
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
throw
|
|
45
|
+
static validateStringArray(value) {
|
|
46
|
+
const string_array_schema = {
|
|
47
|
+
type: 'array',
|
|
48
|
+
items: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
minLength: 1,
|
|
51
|
+
pattern: '\\S',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const validateStringArray = ValidationUtils.ajv.compile(string_array_schema);
|
|
55
|
+
const isValid = validateStringArray(value);
|
|
56
|
+
if (!isValid) {
|
|
57
|
+
throw new errors_argumentError.ArgumentError(`Value must be an array of non-empty strings, got: ${value}`);
|
|
70
58
|
}
|
|
59
|
+
// Allow empty arrays to pass validation - caller should handle early return
|
|
60
|
+
// Non-empty arrays will be validated for string content above
|
|
71
61
|
}
|
|
72
62
|
/**
|
|
73
|
-
* Validates
|
|
74
|
-
*
|
|
75
|
-
* @param validValues Array of valid values
|
|
76
|
-
* @param fieldName The name of the field for error messages
|
|
77
|
-
* @returns The validated value as the enum type
|
|
78
|
-
* @throws ArgumentError if value is not in validValues
|
|
63
|
+
* Validates an attribute assignment object using a single AJV schema.
|
|
64
|
+
* Preserves legacy error messages for each field.
|
|
79
65
|
*/
|
|
80
|
-
static
|
|
81
|
-
const schema =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
66
|
+
static validateAssignment(data, validTypes, fieldNames) {
|
|
67
|
+
const schema = {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
id: { type: 'number', multipleOf: 1 },
|
|
71
|
+
type: { type: 'string', enum: validTypes },
|
|
72
|
+
attributeKey: { type: 'string', minLength: 1 },
|
|
73
|
+
attributeValue: { type: 'string', minLength: 1 },
|
|
74
|
+
},
|
|
75
|
+
required: ['id', 'type', 'attributeKey', 'attributeValue'],
|
|
76
|
+
additionalProperties: false,
|
|
77
|
+
};
|
|
78
|
+
const validate = this.ajv.compile(schema);
|
|
79
|
+
const valid = validate(data);
|
|
80
|
+
if (!valid) {
|
|
81
|
+
// Map to legacy error messages deterministically
|
|
82
|
+
const { id, type, attributeKey, attributeValue } = data;
|
|
83
|
+
// id must be integer
|
|
84
|
+
const isInteger = typeof id === 'number' && Number.isFinite(id) && Math.floor(id) === id;
|
|
85
|
+
if (!isInteger) {
|
|
86
|
+
throw new errors_argumentError.ArgumentError(`${fieldNames.id} must be an integer, got: ${id}`);
|
|
88
87
|
}
|
|
89
|
-
|
|
88
|
+
// type must be within enum
|
|
89
|
+
if (typeof type !== 'string' || !validTypes.includes(type)) {
|
|
90
|
+
throw new errors_argumentError.ArgumentError(`${fieldNames.type} must be one of [${validTypes.join(', ')}], got: ${type}`);
|
|
91
|
+
}
|
|
92
|
+
// attributeKey
|
|
93
|
+
if (typeof attributeKey !== 'string') {
|
|
94
|
+
throw new errors_argumentError.ArgumentError(`attributeKey must be a string, got: ${typeof attributeKey}`);
|
|
95
|
+
}
|
|
96
|
+
if (!attributeKey) {
|
|
97
|
+
throw new errors_argumentError.ArgumentError('attributeKey must be a non-empty string');
|
|
98
|
+
}
|
|
99
|
+
// attributeValue
|
|
100
|
+
if (typeof attributeValue !== 'string') {
|
|
101
|
+
throw new errors_argumentError.ArgumentError(`attributeValue must be a string, got: ${typeof attributeValue}`);
|
|
102
|
+
}
|
|
103
|
+
if (!attributeValue) {
|
|
104
|
+
throw new errors_argumentError.ArgumentError('attributeValue must be a non-empty string');
|
|
105
|
+
}
|
|
106
|
+
// Fallback
|
|
107
|
+
throw new errors_argumentError.ArgumentError('Invalid attribute assignment');
|
|
90
108
|
}
|
|
109
|
+
return {
|
|
110
|
+
id: data.id,
|
|
111
|
+
type: data.type,
|
|
112
|
+
attributeKey: data.attributeKey,
|
|
113
|
+
attributeValue: data.attributeValue,
|
|
114
|
+
};
|
|
91
115
|
}
|
|
92
116
|
/**
|
|
93
|
-
* Validates
|
|
94
|
-
*
|
|
95
|
-
* @param fieldName The name of the field for error messages
|
|
96
|
-
* @throws ArgumentError if any item is not a string
|
|
117
|
+
* Validates a Resource-like object shape: { id: number; type: string }.
|
|
118
|
+
* Throws ArgumentError with legacy-compatible messages.
|
|
97
119
|
*/
|
|
98
|
-
static
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
120
|
+
static validateResource(resource) {
|
|
121
|
+
if (!resource || typeof resource !== 'object') {
|
|
122
|
+
throw new errors_argumentError.ArgumentError('resource must be an object');
|
|
123
|
+
}
|
|
124
|
+
const schema = {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
id: { type: 'number', multipleOf: 1 },
|
|
128
|
+
type: { type: 'string', minLength: 1 },
|
|
129
|
+
wrapperData: { type: 'string' },
|
|
130
|
+
},
|
|
131
|
+
required: ['type', 'id'],
|
|
132
|
+
additionalProperties: false,
|
|
133
|
+
};
|
|
134
|
+
const validate = this.ajv.compile(schema);
|
|
135
|
+
const isValid = validate(resource);
|
|
136
|
+
if (!isValid) {
|
|
137
|
+
throw new errors_argumentError.ArgumentError('Invalid resource');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
static validateArrayTypeOf(attributesMessages, messageClass) {
|
|
141
|
+
const arraySchema = {
|
|
142
|
+
type: 'array',
|
|
143
|
+
};
|
|
144
|
+
const validateArray = ValidationUtils.ajv.compile(arraySchema);
|
|
145
|
+
const isArrayValid = validateArray(attributesMessages);
|
|
146
|
+
if (!isArrayValid) {
|
|
147
|
+
throw new errors_argumentError.ArgumentError(`attributesMessages must be an array`);
|
|
102
148
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
// Check if it's an array item validation error
|
|
108
|
-
if (firstError.path.length > 0 && typeof firstError.path[0] === 'number') {
|
|
109
|
-
const index = firstError.path[0];
|
|
110
|
-
throw new errors_argumentError.ArgumentError(`All ${fieldName} must be strings, but item at index ${index} is not`);
|
|
111
|
-
}
|
|
112
|
-
throw new errors_argumentError.ArgumentError(`${fieldName} must be an array`);
|
|
149
|
+
for (let i = 0; i < attributesMessages.length; i++) {
|
|
150
|
+
const item = attributesMessages[i];
|
|
151
|
+
if (!(item instanceof messageClass)) {
|
|
152
|
+
throw new errors_argumentError.ArgumentError(`attributesMessages[${i}] must be an instance of ${messageClass.name}, got: ${item?.constructor?.name || typeof item}`);
|
|
113
153
|
}
|
|
114
|
-
throw error;
|
|
115
154
|
}
|
|
116
155
|
}
|
|
117
156
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mondaydotcomorg/monday-authorization",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0-feat-shaime-support-entity-attributes-4-49e1de0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -28,11 +28,12 @@
|
|
|
28
28
|
"@mondaydotcomorg/monday-observability-kit": "^1.5.3",
|
|
29
29
|
"@mondaydotcomorg/monday-sns": "^1.2.1",
|
|
30
30
|
"@mondaydotcomorg/trident-backend-api": "^0.24.3",
|
|
31
|
+
"ajv": "^8.17.1",
|
|
32
|
+
"ajv-keywords": "^5.1.0",
|
|
31
33
|
"lodash": "^4.17.21",
|
|
32
34
|
"node-fetch": "^2.6.7",
|
|
33
35
|
"on-headers": "^1.0.2",
|
|
34
|
-
"ts-node": "^10.0.0"
|
|
35
|
-
"zod": "^4.1.13"
|
|
36
|
+
"ts-node": "^10.0.0"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@mondaydotcomorg/trident-library": "^1.1.44",
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { Api, HttpClient } from '@mondaydotcomorg/trident-backend-api';
|
|
2
2
|
import { signAuthorizationHeader } from '@mondaydotcomorg/monday-jwt';
|
|
3
|
-
import { z } from 'zod';
|
|
4
3
|
import { ResourceAttributeAssignment } from './resource-attribute-assignment';
|
|
5
4
|
import { EntityAttributeAssignment } from './entity-attribute-assignment';
|
|
6
5
|
import {
|
|
7
6
|
AttributeOperation,
|
|
8
|
-
EntityType,
|
|
9
7
|
ResourceAttributeOperation,
|
|
10
8
|
EntityAttributeOperation,
|
|
11
9
|
} from './types/authorization-attributes-contracts';
|
|
10
|
+
import { EntityType } from './entity-attributes-constants';
|
|
12
11
|
import { ArgumentError } from './errors/argument-error';
|
|
13
12
|
import { AuthorizationInternalService, logger } from './authorization-internal-service';
|
|
14
13
|
import { getAttributionsFromApi } from './attributions-service';
|
|
15
14
|
import { APP_NAME } from './constants';
|
|
16
15
|
import { ValidationUtils } from './utils/validation';
|
|
17
|
-
import {
|
|
16
|
+
import { AuthorizationAttributesService } from './types/authorization-attributes-service.interface';
|
|
18
17
|
import { Resource } from './types/general';
|
|
19
18
|
const INTERNAL_APP_NAME = 'internal_ms';
|
|
20
19
|
const UPSERT_RESOURCE_ATTRIBUTES_PATH = '/attributes/{accountId}/resource';
|
|
@@ -30,9 +29,14 @@ interface DeleteRequestBody {
|
|
|
30
29
|
* Service class for managing resource attributes in the authorization microservice.
|
|
31
30
|
* Provides synchronous HTTP operations to create/update and delete attributes on resources.
|
|
32
31
|
*/
|
|
33
|
-
export class AuthorizationAttributesMsService implements
|
|
32
|
+
export class AuthorizationAttributesMsService implements AuthorizationAttributesService {
|
|
34
33
|
private static LOG_TAG = 'authorization_attributes_ms';
|
|
35
|
-
private static httpClient: HttpClient |
|
|
34
|
+
private static httpClient: HttpClient | null = Api.getPart('httpClient') ?? null;
|
|
35
|
+
|
|
36
|
+
public static destroyHttpClient(): void {
|
|
37
|
+
AuthorizationAttributesMsService.httpClient = null;
|
|
38
|
+
}
|
|
39
|
+
|
|
36
40
|
/**
|
|
37
41
|
* Creates or updates resource attributes synchronously.
|
|
38
42
|
* @param accountId The account ID
|
|
@@ -70,22 +74,14 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
|
|
|
70
74
|
_appName?: string,
|
|
71
75
|
_callerActionIdentifier?: string
|
|
72
76
|
): Promise<void> {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
throw new ArgumentError('resource must be an object');
|
|
76
|
-
}
|
|
77
|
-
if (!resource.id) {
|
|
78
|
-
throw new ArgumentError('resource.id is required');
|
|
79
|
-
}
|
|
80
|
-
ValidationUtils.validateInteger(resource.id, 'resource.id');
|
|
81
|
-
ValidationUtils.validateString(resource.type, 'resource.type');
|
|
82
|
-
|
|
77
|
+
ValidationUtils.validateResource(resource);
|
|
78
|
+
ValidationUtils.validateStringArray(attributeKeys);
|
|
83
79
|
return AuthorizationAttributesMsService.executeDeleteRequest(
|
|
84
80
|
accountId,
|
|
85
81
|
DELETE_RESOURCE_ATTRIBUTES_PATH,
|
|
86
82
|
{
|
|
87
83
|
resourceType: resource.type,
|
|
88
|
-
resourceId: resource.id,
|
|
84
|
+
resourceId: resource.id as number,
|
|
89
85
|
},
|
|
90
86
|
attributeKeys,
|
|
91
87
|
'resource',
|
|
@@ -127,7 +123,7 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
|
|
|
127
123
|
*/
|
|
128
124
|
async deleteEntityAttributes(
|
|
129
125
|
accountId: number,
|
|
130
|
-
entityType: EntityType
|
|
126
|
+
entityType: EntityType,
|
|
131
127
|
entityId: number,
|
|
132
128
|
attributeKeys: string[],
|
|
133
129
|
_appName?: string,
|
|
@@ -136,7 +132,7 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
|
|
|
136
132
|
if (!entityType || typeof entityType !== 'string' || entityType.trim() === '') {
|
|
137
133
|
throw new ArgumentError(`entityType must be a non-empty string, got: ${entityType}`);
|
|
138
134
|
}
|
|
139
|
-
ValidationUtils.validateInteger(entityId
|
|
135
|
+
ValidationUtils.validateInteger(entityId);
|
|
140
136
|
|
|
141
137
|
return AuthorizationAttributesMsService.executeDeleteRequest(
|
|
142
138
|
accountId,
|
|
@@ -262,21 +258,14 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
|
|
|
262
258
|
context: Record<string, any> = {}
|
|
263
259
|
): Promise<void> {
|
|
264
260
|
// Validate inputs
|
|
265
|
-
ValidationUtils.validateInteger(accountId
|
|
266
|
-
ValidationUtils.
|
|
261
|
+
ValidationUtils.validateInteger(accountId);
|
|
262
|
+
ValidationUtils.validateStringArray(keys);
|
|
267
263
|
|
|
268
264
|
if (!keys.length) {
|
|
269
265
|
logger.warn({ tag: this.LOG_TAG, accountId, ...pathParams }, `${methodName} called with empty keys array`);
|
|
270
266
|
return;
|
|
271
267
|
}
|
|
272
|
-
|
|
273
|
-
// Validate all keys are strings
|
|
274
|
-
ValidationUtils.validateStringArray(keys, 'attributeKeys');
|
|
275
|
-
|
|
276
|
-
// Build request body
|
|
277
|
-
const requestBody: DeleteRequestBody = {
|
|
278
|
-
keys,
|
|
279
|
-
};
|
|
268
|
+
const requestBody: DeleteRequestBody = { keys };
|
|
280
269
|
|
|
281
270
|
if (!AuthorizationAttributesMsService.httpClient) {
|
|
282
271
|
throw new Error('AuthorizationAttributesMsService: HTTP client is not initialized');
|
|
@@ -306,7 +295,7 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
|
|
|
306
295
|
}
|
|
307
296
|
);
|
|
308
297
|
|
|
309
|
-
logger.
|
|
298
|
+
logger.debug(
|
|
310
299
|
{ tag: AuthorizationAttributesMsService.LOG_TAG, accountId, ...pathParams, keys },
|
|
311
300
|
`Successfully deleted ${logPrefix} attributes`
|
|
312
301
|
);
|
|
@@ -376,63 +365,6 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
|
|
|
376
365
|
return headers;
|
|
377
366
|
}
|
|
378
367
|
|
|
379
|
-
/**
|
|
380
|
-
* Validates that all messages are instances of the specified message class
|
|
381
|
-
*/
|
|
382
|
-
private static validateMessages<T>(attributesMessages: T[], messageClass: abstract new (...args: any[]) => T): void {
|
|
383
|
-
// Validate messageClass is a function using Zod
|
|
384
|
-
const classSchema = z.custom<abstract new (...args: any[]) => T>(value => typeof value === 'function', {
|
|
385
|
-
message: 'messageClass must be a class/constructor function',
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
try {
|
|
389
|
-
classSchema.parse(messageClass);
|
|
390
|
-
} catch (error) {
|
|
391
|
-
if (error instanceof z.ZodError) {
|
|
392
|
-
const firstError = error.issues[0];
|
|
393
|
-
throw new ArgumentError(firstError.message);
|
|
394
|
-
}
|
|
395
|
-
throw error;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const className = messageClass.name || 'ResourceAttributeAssignment';
|
|
399
|
-
|
|
400
|
-
// First validate it's an array
|
|
401
|
-
ValidationUtils.validateArray(attributesMessages, 'attributesMessages');
|
|
402
|
-
|
|
403
|
-
// Then use Zod to validate each item is an instance of the class
|
|
404
|
-
const schema = z.array(z.any()).refine(
|
|
405
|
-
items => {
|
|
406
|
-
for (let i = 0; i < items.length; i++) {
|
|
407
|
-
if (!(items[i] instanceof messageClass)) {
|
|
408
|
-
return false;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return true;
|
|
412
|
-
},
|
|
413
|
-
{
|
|
414
|
-
message: `All attributesMessages must be instances of ${className}`,
|
|
415
|
-
}
|
|
416
|
-
);
|
|
417
|
-
|
|
418
|
-
try {
|
|
419
|
-
schema.parse(attributesMessages);
|
|
420
|
-
} catch (error) {
|
|
421
|
-
if (error instanceof z.ZodError) {
|
|
422
|
-
// Find the first invalid index for a more specific error message
|
|
423
|
-
const invalidIndex = attributesMessages.findIndex(item => !(item instanceof messageClass));
|
|
424
|
-
if (invalidIndex !== -1) {
|
|
425
|
-
throw new ArgumentError(
|
|
426
|
-
`All attributesMessages must be instances of ${className}, but item at index ${invalidIndex} is not`
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
const firstError = error.issues[0];
|
|
430
|
-
throw new ArgumentError(firstError.message);
|
|
431
|
-
}
|
|
432
|
-
throw error;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
368
|
/**
|
|
437
369
|
* Generic helper for executing upsert requests
|
|
438
370
|
*/
|
|
@@ -445,20 +377,11 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
|
|
|
445
377
|
logPrefix: string,
|
|
446
378
|
methodName: string
|
|
447
379
|
): Promise<void> {
|
|
448
|
-
|
|
449
|
-
ValidationUtils.
|
|
450
|
-
ValidationUtils.validateArray(assignments, 'assignments');
|
|
451
|
-
|
|
380
|
+
ValidationUtils.validateInteger(accountId);
|
|
381
|
+
ValidationUtils.validateArrayTypeOf(assignments, assignmentClass);
|
|
452
382
|
if (!assignments.length) {
|
|
453
|
-
logger.warn(
|
|
454
|
-
{ tag: AuthorizationAttributesMsService.LOG_TAG, accountId },
|
|
455
|
-
`${methodName} called with empty array`
|
|
456
|
-
);
|
|
457
383
|
return;
|
|
458
384
|
}
|
|
459
|
-
|
|
460
|
-
// Validate all assignments are instances of the correct class
|
|
461
|
-
AuthorizationAttributesMsService.validateMessages(assignments, assignmentClass);
|
|
462
385
|
const assignmentDto = assignments.map(assignment => assignment.toDataTransferObject());
|
|
463
386
|
|
|
464
387
|
const requestBody =
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { AuthorizationAttributesMsService } from './authorization-attributes-ms-service';
|
|
2
2
|
import { AuthorizationAttributesSnsService } from './authorization-attributes-sns-service';
|
|
3
|
-
import { IAuthorizationAttributesService } from './types/authorization-attributes-service.interface';
|
|
3
|
+
import { AuthorizationAttributesService as IAuthorizationAttributesService } from './types/authorization-attributes-service.interface';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Main service class for managing resource and entity attributes.
|
|
7
7
|
* Provides access to both direct (MS) and SNS operations.
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
|
-
* ```typescript
|
|
11
10
|
* const service = new AuthorizationAttributesService();
|
|
12
11
|
*
|
|
13
12
|
* // Use direct operations
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
ResourceAttributeOperation,
|
|
6
6
|
EntityAttributeOperation,
|
|
7
7
|
AttributeOperation,
|
|
8
|
-
EntityType,
|
|
9
8
|
} from './types/authorization-attributes-contracts';
|
|
10
9
|
import { EntityAttributeAssignment } from './entity-attribute-assignment';
|
|
11
10
|
import { Resource } from './types/general';
|
|
@@ -22,13 +21,14 @@ import {
|
|
|
22
21
|
SnsTopicType,
|
|
23
22
|
} from './constants/sns';
|
|
24
23
|
import type { TopicAttributesMap } from 'aws-sdk/clients/sns';
|
|
25
|
-
import {
|
|
24
|
+
import { AuthorizationAttributesService } from './types/authorization-attributes-service.interface';
|
|
25
|
+
import { EntityType } from './entity-attributes-constants';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Service class for managing resource attributes asynchronously via SNS.
|
|
29
29
|
* Provides asynchronous operations to create/update and delete attributes on resources.
|
|
30
30
|
*/
|
|
31
|
-
export class AuthorizationAttributesSnsService implements
|
|
31
|
+
export class AuthorizationAttributesSnsService implements AuthorizationAttributesService {
|
|
32
32
|
private static LOG_TAG = 'authorization_attributes';
|
|
33
33
|
private resourceSnsArn: string;
|
|
34
34
|
private entitySnsArn: string;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import onHeaders from 'on-headers';
|
|
2
2
|
import { AuthorizationInternalService } from './authorization-internal-service';
|
|
3
3
|
import { AuthorizationService, createAuthorizationParams } from './authorization-service';
|
|
4
|
-
import { BaseRequest, BaseResponse, Context, ContextGetter, ResourceGetter } from './types/general';
|
|
4
|
+
import { Action, BaseRequest, BaseResponse, Context, ContextGetter, ResourceGetter } from './types/general';
|
|
5
5
|
import type { NextFunction } from 'express';
|
|
6
6
|
|
|
7
7
|
// getAuthorizationMiddleware is duplicated in testKit/index.ts
|
|
8
8
|
// If you are making changes to this function, please make sure to update the other file as well
|
|
9
9
|
export function getAuthorizationMiddleware(
|
|
10
|
-
action:
|
|
10
|
+
action: Action,
|
|
11
11
|
resourceGetter: ResourceGetter,
|
|
12
12
|
contextGetter?: ContextGetter
|
|
13
13
|
) {
|
|
@@ -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 { AuthorizationObject, AuthorizationParams, Resource } from './types/general';
|
|
6
|
+
import { Action, 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: Action
|
|
78
78
|
): Promise<AuthorizeResponse>;
|
|
79
79
|
|
|
80
80
|
static async isAuthorized(
|
|
@@ -223,7 +223,7 @@ export class AuthorizationService {
|
|
|
223
223
|
accountId: number,
|
|
224
224
|
userId: number,
|
|
225
225
|
resources: Resource[],
|
|
226
|
-
action:
|
|
226
|
+
action: Action
|
|
227
227
|
): Promise<AuthorizeResponse> {
|
|
228
228
|
const { authorizationObjects } = createAuthorizationParams(resources, action);
|
|
229
229
|
return this.isAuthorizedMultiple(accountId, userId, authorizationObjects);
|
|
@@ -338,7 +338,7 @@ export async function setIgniteClient() {
|
|
|
338
338
|
AuthorizationInternalService.setIgniteClient(igniteClient);
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
export function createAuthorizationParams(resources: Resource[], action:
|
|
341
|
+
export function createAuthorizationParams(resources: Resource[], action: Action): AuthorizationParams {
|
|
342
342
|
const params = {
|
|
343
343
|
authorizationObjects: resources.map((resource: Resource) => {
|
|
344
344
|
const authorizationObject: AuthorizationObject = {
|