@mondaydotcomorg/monday-authorization 2.1.1 → 3.0.0-feature-bashanye-create-custom-roles-sdk.b34d2d3
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-service.d.ts +17 -8
- package/dist/authorization-attributes-service.d.ts.map +1 -1
- package/dist/authorization-attributes-service.js +89 -45
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +22 -0
- package/dist/esm/authorization-attributes-service.d.ts +17 -8
- package/dist/esm/authorization-attributes-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-service.mjs +90 -46
- package/dist/esm/constants.d.ts +9 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.mjs +18 -0
- package/dist/esm/roles.d.ts +25 -0
- package/dist/esm/roles.d.ts.map +1 -0
- package/dist/esm/roles.mjs +99 -0
- package/dist/esm/types/roles.d.ts +29 -0
- package/dist/esm/types/roles.d.ts.map +1 -0
- package/dist/esm/types/roles.mjs +7 -0
- package/dist/roles.d.ts +25 -0
- package/dist/roles.d.ts.map +1 -0
- package/dist/roles.js +101 -0
- package/dist/types/roles.d.ts +29 -0
- package/dist/types/roles.d.ts.map +1 -0
- package/dist/types/roles.js +7 -0
- package/package.json +1 -1
|
@@ -1,25 +1,35 @@
|
|
|
1
|
+
import { FetcherConfig, HttpClient } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
+
import { RecursivePartial } from '@mondaydotcomorg/monday-fetch-api';
|
|
1
3
|
import { ResourceAttributeAssignment, ResourceAttributeResponse, ResourceAttributesOperation } from './types/authorization-attributes-contracts';
|
|
2
4
|
import { Resource } from './types/general';
|
|
3
5
|
export declare class AuthorizationAttributesService {
|
|
4
6
|
private static LOG_TAG;
|
|
7
|
+
private static API_PATHS;
|
|
8
|
+
private httpClient;
|
|
9
|
+
private fetchOptions;
|
|
10
|
+
private snsArn;
|
|
11
|
+
/**
|
|
12
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
13
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
14
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
15
|
+
*/
|
|
16
|
+
constructor(httpClient?: HttpClient, fetchOptions?: RecursivePartial<FetcherConfig>);
|
|
5
17
|
/**
|
|
6
18
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
7
19
|
* @param accountId
|
|
8
|
-
* @param userId
|
|
9
20
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
10
21
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
11
22
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
12
23
|
*/
|
|
13
|
-
|
|
24
|
+
upsertResourceAttributes(accountId: number, resourceAttributeAssignments: ResourceAttributeAssignment[]): Promise<ResourceAttributeResponse>;
|
|
14
25
|
/**
|
|
15
26
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
16
27
|
* @param accountId
|
|
17
|
-
* @param userId
|
|
18
28
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
19
29
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
20
30
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
21
31
|
*/
|
|
22
|
-
|
|
32
|
+
deleteResourceAttributes(accountId: number, resource: Resource, attributeKeys: string[]): Promise<ResourceAttributeResponse>;
|
|
23
33
|
/**
|
|
24
34
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
25
35
|
* @param accountId
|
|
@@ -28,10 +38,9 @@ export declare class AuthorizationAttributesService {
|
|
|
28
38
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
29
39
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
30
40
|
* */
|
|
31
|
-
|
|
32
|
-
private
|
|
41
|
+
updateResourceAttributesAsync(accountId: number, appName: string, callerActionIdentifier: string, resourceAttributeOperations: ResourceAttributesOperation[]): Promise<ResourceAttributesOperation[]>;
|
|
42
|
+
private sendSingleSnsMessage;
|
|
33
43
|
private static getSnsTopicArn;
|
|
34
|
-
private static getResourceAttributesUrl;
|
|
35
44
|
/**
|
|
36
45
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
37
46
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -40,6 +49,6 @@ export declare class AuthorizationAttributesService {
|
|
|
40
49
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
41
50
|
* @return {Promise<boolean>} - true if succeeded
|
|
42
51
|
*/
|
|
43
|
-
|
|
52
|
+
asyncResourceAttributesHealthCheck(): Promise<boolean>;
|
|
44
53
|
}
|
|
45
54
|
//# sourceMappingURL=authorization-attributes-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-attributes-service.d.ts","sourceRoot":"","sources":["../src/authorization-attributes-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authorization-attributes-service.d.ts","sourceRoot":"","sources":["../src/authorization-attributes-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAO,aAAa,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAEtF,OAAO,EAAoB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAW3C,qBAAa,8BAA8B;IACzC,OAAO,CAAC,MAAM,CAAC,OAAO,CAA8B;IACpD,OAAO,CAAC,MAAM,CAAC,SAAS,CAGb;IACX,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;OAIG;gBACS,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAqBnF;;;;;;OAMG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,4BAA4B,EAAE,2BAA2B,EAAE,GAC1D,OAAO,CAAC,yBAAyB,CAAC;IA6BrC;;;;;;OAMG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,yBAAyB,CAAC;IAkCrC;;;;;;;UAOM;IACA,6BAA6B,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,sBAAsB,EAAE,MAAM,EAC9B,2BAA2B,EAAE,2BAA2B,EAAE,GACzD,OAAO,CAAC,2BAA2B,EAAE,CAAC;YAY3B,oBAAoB;IA4BlC,OAAO,CAAC,MAAM,CAAC,cAAc;IAe7B;;;;;;;OAOG;IACG,kCAAkC,IAAI,OAAO,CAAC,OAAO,CAAC;CAoB7D"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
const chunk = require('lodash/chunk.js');
|
|
4
|
-
const mondayFetch = require('@mondaydotcomorg/monday-fetch');
|
|
5
4
|
const tridentBackendApi = require('@mondaydotcomorg/trident-backend-api');
|
|
6
5
|
const mondaySns = require('@mondaydotcomorg/monday-sns');
|
|
6
|
+
const mondayFetchApi = require('@mondaydotcomorg/monday-fetch-api');
|
|
7
7
|
const authorizationInternalService = require('./authorization-internal-service.js');
|
|
8
8
|
const attributionsService = require('./attributions-service.js');
|
|
9
9
|
const constants_sns = require('./constants/sns.js');
|
|
10
|
+
const constants = require('./constants.js');
|
|
10
11
|
|
|
11
12
|
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
12
13
|
|
|
@@ -14,56 +15,102 @@ const chunk__default = /*#__PURE__*/_interopDefault(chunk);
|
|
|
14
15
|
|
|
15
16
|
class AuthorizationAttributesService {
|
|
16
17
|
static LOG_TAG = 'authorization_attributes';
|
|
18
|
+
static API_PATHS = {
|
|
19
|
+
UPSERT_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource',
|
|
20
|
+
DELETE_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource/{resourceType}/{resourceId}',
|
|
21
|
+
};
|
|
22
|
+
httpClient;
|
|
23
|
+
fetchOptions;
|
|
24
|
+
snsArn;
|
|
25
|
+
/**
|
|
26
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
27
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
28
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
29
|
+
*/
|
|
30
|
+
constructor(httpClient, fetchOptions) {
|
|
31
|
+
if (!httpClient) {
|
|
32
|
+
httpClient = tridentBackendApi.Api.getPart('httpClient');
|
|
33
|
+
if (!httpClient) {
|
|
34
|
+
throw new Error(constants.ERROR_MESSAGES.HTTP_CLIENT_NOT_INITIALIZED);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!fetchOptions) {
|
|
38
|
+
fetchOptions = constants.DEFAULT_FETCH_OPTIONS;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
fetchOptions = {
|
|
42
|
+
...constants.DEFAULT_FETCH_OPTIONS,
|
|
43
|
+
...fetchOptions,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
this.httpClient = httpClient;
|
|
47
|
+
this.fetchOptions = fetchOptions;
|
|
48
|
+
this.snsArn = AuthorizationAttributesService.getSnsTopicArn();
|
|
49
|
+
}
|
|
17
50
|
/**
|
|
18
51
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
19
52
|
* @param accountId
|
|
20
|
-
* @param userId
|
|
21
53
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
22
54
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
23
55
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
24
56
|
*/
|
|
25
|
-
|
|
26
|
-
const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
57
|
+
async upsertResourceAttributes(accountId, resourceAttributeAssignments) {
|
|
27
58
|
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
try {
|
|
60
|
+
return await this.httpClient.fetch({
|
|
61
|
+
url: {
|
|
62
|
+
appName: constants.APP_NAME,
|
|
63
|
+
path: AuthorizationAttributesService.API_PATHS.UPSERT_RESOURCE_ATTRIBUTES.replace('{accountId}', accountId.toString()),
|
|
64
|
+
},
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: {
|
|
67
|
+
'Content-Type': 'application/json',
|
|
68
|
+
...attributionHeaders,
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify({ resourceAttributeAssignments }),
|
|
71
|
+
}, this.fetchOptions);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
75
|
+
throw new Error(constants.ERROR_MESSAGES.REQUEST_FAILED('upsertResourceAttributes', err.status, err.message));
|
|
76
|
+
}
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
41
79
|
}
|
|
42
80
|
/**
|
|
43
81
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
44
82
|
* @param accountId
|
|
45
|
-
* @param userId
|
|
46
83
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
47
84
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
48
85
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
49
86
|
*/
|
|
50
|
-
|
|
51
|
-
const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
52
|
-
const url = `${this.getResourceAttributesUrl(accountId)}/${resource.type}/${resource.id}`;
|
|
87
|
+
async deleteResourceAttributes(accountId, resource, attributeKeys) {
|
|
53
88
|
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
if (!resource.id) {
|
|
90
|
+
throw new Error('Resource ID is required');
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
return await this.httpClient.fetch({
|
|
94
|
+
url: {
|
|
95
|
+
appName: constants.APP_NAME,
|
|
96
|
+
path: AuthorizationAttributesService.API_PATHS.DELETE_RESOURCE_ATTRIBUTES.replace('{accountId}', accountId.toString())
|
|
97
|
+
.replace('{resourceType}', resource.type)
|
|
98
|
+
.replace('{resourceId}', resource.id.toString()),
|
|
99
|
+
},
|
|
100
|
+
method: 'DELETE',
|
|
101
|
+
headers: {
|
|
102
|
+
'Content-Type': 'application/json',
|
|
103
|
+
...attributionHeaders,
|
|
104
|
+
},
|
|
105
|
+
body: JSON.stringify({ keys: attributeKeys }),
|
|
106
|
+
}, this.fetchOptions);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
110
|
+
throw new Error(constants.ERROR_MESSAGES.REQUEST_FAILED('deleteResourceAttributes', err.status, err.message));
|
|
111
|
+
}
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
67
114
|
}
|
|
68
115
|
/**
|
|
69
116
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
@@ -73,8 +120,8 @@ class AuthorizationAttributesService {
|
|
|
73
120
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
74
121
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
75
122
|
* */
|
|
76
|
-
|
|
77
|
-
const topicArn = this.
|
|
123
|
+
async updateResourceAttributesAsync(accountId, appName, callerActionIdentifier, resourceAttributeOperations) {
|
|
124
|
+
const topicArn = this.snsArn;
|
|
78
125
|
const sendToSnsPromises = [];
|
|
79
126
|
const operationChucks = chunk__default.default(resourceAttributeOperations, constants_sns.ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE);
|
|
80
127
|
for (const operationsChunk of operationChucks) {
|
|
@@ -82,7 +129,7 @@ class AuthorizationAttributesService {
|
|
|
82
129
|
}
|
|
83
130
|
return (await Promise.all(sendToSnsPromises)).flat();
|
|
84
131
|
}
|
|
85
|
-
|
|
132
|
+
async sendSingleSnsMessage(topicArn, accountId, appName, callerActionIdentifier, operations) {
|
|
86
133
|
const payload = {
|
|
87
134
|
kind: constants_sns.RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND,
|
|
88
135
|
payload: {
|
|
@@ -97,7 +144,7 @@ class AuthorizationAttributesService {
|
|
|
97
144
|
return operations;
|
|
98
145
|
}
|
|
99
146
|
catch (error) {
|
|
100
|
-
authorizationInternalService.logger.error({ error, tag:
|
|
147
|
+
authorizationInternalService.logger.error({ error, tag: AuthorizationAttributesService.LOG_TAG }, 'Authorization resource attributes async update: failed to send operations to SNS');
|
|
101
148
|
return [];
|
|
102
149
|
}
|
|
103
150
|
}
|
|
@@ -113,9 +160,6 @@ class AuthorizationAttributesService {
|
|
|
113
160
|
}
|
|
114
161
|
throw new Error('Unable to get sns topic arn from env variable');
|
|
115
162
|
}
|
|
116
|
-
static getResourceAttributesUrl(accountId) {
|
|
117
|
-
return `${process.env.AUTHORIZATION_URL}/attributes/${accountId}/resource`;
|
|
118
|
-
}
|
|
119
163
|
/**
|
|
120
164
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
121
165
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -124,18 +168,18 @@ class AuthorizationAttributesService {
|
|
|
124
168
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
125
169
|
* @return {Promise<boolean>} - true if succeeded
|
|
126
170
|
*/
|
|
127
|
-
|
|
171
|
+
async asyncResourceAttributesHealthCheck() {
|
|
128
172
|
try {
|
|
129
|
-
const requestedTopicArn = this.
|
|
173
|
+
const requestedTopicArn = this.snsArn;
|
|
130
174
|
const attributes = await mondaySns.getTopicAttributes(requestedTopicArn);
|
|
131
175
|
const isHealthy = !(!attributes || !('TopicArn' in attributes) || attributes.TopicArn !== requestedTopicArn);
|
|
132
176
|
if (!isHealthy) {
|
|
133
|
-
authorizationInternalService.logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag:
|
|
177
|
+
authorizationInternalService.logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag: AuthorizationAttributesService.LOG_TAG }, 'authorization-attributes-service failed in health check');
|
|
134
178
|
}
|
|
135
179
|
return isHealthy;
|
|
136
180
|
}
|
|
137
181
|
catch (error) {
|
|
138
|
-
authorizationInternalService.logger.error({ error, tag:
|
|
182
|
+
authorizationInternalService.logger.error({ error, tag: AuthorizationAttributesService.LOG_TAG }, 'authorization-attributes-service got error during health check');
|
|
139
183
|
return false;
|
|
140
184
|
}
|
|
141
185
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RecursivePartial } from "@mondaydotcomorg/monday-fetch-api";
|
|
2
|
+
import { FetcherConfig } from "@mondaydotcomorg/trident-backend-api";
|
|
3
|
+
export declare const APP_NAME = "authorization";
|
|
4
|
+
export declare const ERROR_MESSAGES: {
|
|
5
|
+
readonly HTTP_CLIENT_NOT_INITIALIZED: "MondayAuthorization: HTTP client is not initialized";
|
|
6
|
+
readonly REQUEST_FAILED: (method: string, status: number, reason: string) => string;
|
|
7
|
+
};
|
|
8
|
+
export declare const DEFAULT_FETCH_OPTIONS: RecursivePartial<FetcherConfig>;
|
|
9
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAUjE,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const APP_NAME = 'authorization';
|
|
4
|
+
const ERROR_MESSAGES = {
|
|
5
|
+
HTTP_CLIENT_NOT_INITIALIZED: 'MondayAuthorization: HTTP client is not initialized',
|
|
6
|
+
REQUEST_FAILED: (method, status, reason) => `MondayAuthorization: [${method}] request failed with status ${status} with reason: ${reason}`,
|
|
7
|
+
};
|
|
8
|
+
const DEFAULT_FETCH_OPTIONS = {
|
|
9
|
+
retryPolicy: {
|
|
10
|
+
useRetries: true,
|
|
11
|
+
maxRetries: 3,
|
|
12
|
+
retryDelayMS: 10,
|
|
13
|
+
},
|
|
14
|
+
logPolicy: {
|
|
15
|
+
logErrors: 'error',
|
|
16
|
+
logRequests: 'info',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
exports.APP_NAME = APP_NAME;
|
|
21
|
+
exports.DEFAULT_FETCH_OPTIONS = DEFAULT_FETCH_OPTIONS;
|
|
22
|
+
exports.ERROR_MESSAGES = ERROR_MESSAGES;
|
|
@@ -1,25 +1,35 @@
|
|
|
1
|
+
import { FetcherConfig, HttpClient } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
+
import { RecursivePartial } from '@mondaydotcomorg/monday-fetch-api';
|
|
1
3
|
import { ResourceAttributeAssignment, ResourceAttributeResponse, ResourceAttributesOperation } from './types/authorization-attributes-contracts';
|
|
2
4
|
import { Resource } from './types/general';
|
|
3
5
|
export declare class AuthorizationAttributesService {
|
|
4
6
|
private static LOG_TAG;
|
|
7
|
+
private static API_PATHS;
|
|
8
|
+
private httpClient;
|
|
9
|
+
private fetchOptions;
|
|
10
|
+
private snsArn;
|
|
11
|
+
/**
|
|
12
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
13
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
14
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
15
|
+
*/
|
|
16
|
+
constructor(httpClient?: HttpClient, fetchOptions?: RecursivePartial<FetcherConfig>);
|
|
5
17
|
/**
|
|
6
18
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
7
19
|
* @param accountId
|
|
8
|
-
* @param userId
|
|
9
20
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
10
21
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
11
22
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
12
23
|
*/
|
|
13
|
-
|
|
24
|
+
upsertResourceAttributes(accountId: number, resourceAttributeAssignments: ResourceAttributeAssignment[]): Promise<ResourceAttributeResponse>;
|
|
14
25
|
/**
|
|
15
26
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
16
27
|
* @param accountId
|
|
17
|
-
* @param userId
|
|
18
28
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
19
29
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
20
30
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
21
31
|
*/
|
|
22
|
-
|
|
32
|
+
deleteResourceAttributes(accountId: number, resource: Resource, attributeKeys: string[]): Promise<ResourceAttributeResponse>;
|
|
23
33
|
/**
|
|
24
34
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
25
35
|
* @param accountId
|
|
@@ -28,10 +38,9 @@ export declare class AuthorizationAttributesService {
|
|
|
28
38
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
29
39
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
30
40
|
* */
|
|
31
|
-
|
|
32
|
-
private
|
|
41
|
+
updateResourceAttributesAsync(accountId: number, appName: string, callerActionIdentifier: string, resourceAttributeOperations: ResourceAttributesOperation[]): Promise<ResourceAttributesOperation[]>;
|
|
42
|
+
private sendSingleSnsMessage;
|
|
33
43
|
private static getSnsTopicArn;
|
|
34
|
-
private static getResourceAttributesUrl;
|
|
35
44
|
/**
|
|
36
45
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
37
46
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -40,6 +49,6 @@ export declare class AuthorizationAttributesService {
|
|
|
40
49
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
41
50
|
* @return {Promise<boolean>} - true if succeeded
|
|
42
51
|
*/
|
|
43
|
-
|
|
52
|
+
asyncResourceAttributesHealthCheck(): Promise<boolean>;
|
|
44
53
|
}
|
|
45
54
|
//# sourceMappingURL=authorization-attributes-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-attributes-service.d.ts","sourceRoot":"","sources":["../../src/authorization-attributes-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authorization-attributes-service.d.ts","sourceRoot":"","sources":["../../src/authorization-attributes-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAO,aAAa,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAEtF,OAAO,EAAoB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAW3C,qBAAa,8BAA8B;IACzC,OAAO,CAAC,MAAM,CAAC,OAAO,CAA8B;IACpD,OAAO,CAAC,MAAM,CAAC,SAAS,CAGb;IACX,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;OAIG;gBACS,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAqBnF;;;;;;OAMG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,4BAA4B,EAAE,2BAA2B,EAAE,GAC1D,OAAO,CAAC,yBAAyB,CAAC;IA6BrC;;;;;;OAMG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,yBAAyB,CAAC;IAkCrC;;;;;;;UAOM;IACA,6BAA6B,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,sBAAsB,EAAE,MAAM,EAC9B,2BAA2B,EAAE,2BAA2B,EAAE,GACzD,OAAO,CAAC,2BAA2B,EAAE,CAAC;YAY3B,oBAAoB;IA4BlC,OAAO,CAAC,MAAM,CAAC,cAAc;IAe7B;;;;;;;OAOG;IACG,kCAAkC,IAAI,OAAO,CAAC,OAAO,CAAC;CAoB7D"}
|
|
@@ -1,63 +1,110 @@
|
|
|
1
1
|
import chunk from 'lodash/chunk.js';
|
|
2
|
-
import { fetch } from '@mondaydotcomorg/monday-fetch';
|
|
3
2
|
import { Api } from '@mondaydotcomorg/trident-backend-api';
|
|
4
3
|
import { sendToSns, getTopicAttributes } from '@mondaydotcomorg/monday-sns';
|
|
5
|
-
import {
|
|
4
|
+
import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
|
|
5
|
+
import { logger } from './authorization-internal-service.mjs';
|
|
6
6
|
import { getAttributionsFromApi } from './attributions-service.mjs';
|
|
7
7
|
import { ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE, RESOURCE_ATTRIBUTES_SNS_ARN_SECRET_NAME, RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND } from './constants/sns.mjs';
|
|
8
|
+
import { ERROR_MESSAGES, DEFAULT_FETCH_OPTIONS, APP_NAME } from './constants.mjs';
|
|
8
9
|
|
|
9
10
|
class AuthorizationAttributesService {
|
|
10
11
|
static LOG_TAG = 'authorization_attributes';
|
|
12
|
+
static API_PATHS = {
|
|
13
|
+
UPSERT_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource',
|
|
14
|
+
DELETE_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource/{resourceType}/{resourceId}',
|
|
15
|
+
};
|
|
16
|
+
httpClient;
|
|
17
|
+
fetchOptions;
|
|
18
|
+
snsArn;
|
|
19
|
+
/**
|
|
20
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
21
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
22
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
23
|
+
*/
|
|
24
|
+
constructor(httpClient, fetchOptions) {
|
|
25
|
+
if (!httpClient) {
|
|
26
|
+
httpClient = Api.getPart('httpClient');
|
|
27
|
+
if (!httpClient) {
|
|
28
|
+
throw new Error(ERROR_MESSAGES.HTTP_CLIENT_NOT_INITIALIZED);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (!fetchOptions) {
|
|
32
|
+
fetchOptions = DEFAULT_FETCH_OPTIONS;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
fetchOptions = {
|
|
36
|
+
...DEFAULT_FETCH_OPTIONS,
|
|
37
|
+
...fetchOptions,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
this.httpClient = httpClient;
|
|
41
|
+
this.fetchOptions = fetchOptions;
|
|
42
|
+
this.snsArn = AuthorizationAttributesService.getSnsTopicArn();
|
|
43
|
+
}
|
|
11
44
|
/**
|
|
12
45
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
13
46
|
* @param accountId
|
|
14
|
-
* @param userId
|
|
15
47
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
16
48
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
17
49
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
18
50
|
*/
|
|
19
|
-
|
|
20
|
-
const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
51
|
+
async upsertResourceAttributes(accountId, resourceAttributeAssignments) {
|
|
21
52
|
const attributionHeaders = getAttributionsFromApi();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
53
|
+
try {
|
|
54
|
+
return await this.httpClient.fetch({
|
|
55
|
+
url: {
|
|
56
|
+
appName: APP_NAME,
|
|
57
|
+
path: AuthorizationAttributesService.API_PATHS.UPSERT_RESOURCE_ATTRIBUTES.replace('{accountId}', accountId.toString()),
|
|
58
|
+
},
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: {
|
|
61
|
+
'Content-Type': 'application/json',
|
|
62
|
+
...attributionHeaders,
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify({ resourceAttributeAssignments }),
|
|
65
|
+
}, this.fetchOptions);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
if (err instanceof HttpFetcherError) {
|
|
69
|
+
throw new Error(ERROR_MESSAGES.REQUEST_FAILED('upsertResourceAttributes', err.status, err.message));
|
|
70
|
+
}
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
35
73
|
}
|
|
36
74
|
/**
|
|
37
75
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
38
76
|
* @param accountId
|
|
39
|
-
* @param userId
|
|
40
77
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
41
78
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
42
79
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
43
80
|
*/
|
|
44
|
-
|
|
45
|
-
const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
46
|
-
const url = `${this.getResourceAttributesUrl(accountId)}/${resource.type}/${resource.id}`;
|
|
81
|
+
async deleteResourceAttributes(accountId, resource, attributeKeys) {
|
|
47
82
|
const attributionHeaders = getAttributionsFromApi();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
83
|
+
if (!resource.id) {
|
|
84
|
+
throw new Error('Resource ID is required');
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
return await this.httpClient.fetch({
|
|
88
|
+
url: {
|
|
89
|
+
appName: APP_NAME,
|
|
90
|
+
path: AuthorizationAttributesService.API_PATHS.DELETE_RESOURCE_ATTRIBUTES.replace('{accountId}', accountId.toString())
|
|
91
|
+
.replace('{resourceType}', resource.type)
|
|
92
|
+
.replace('{resourceId}', resource.id.toString()),
|
|
93
|
+
},
|
|
94
|
+
method: 'DELETE',
|
|
95
|
+
headers: {
|
|
96
|
+
'Content-Type': 'application/json',
|
|
97
|
+
...attributionHeaders,
|
|
98
|
+
},
|
|
99
|
+
body: JSON.stringify({ keys: attributeKeys }),
|
|
100
|
+
}, this.fetchOptions);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
if (err instanceof HttpFetcherError) {
|
|
104
|
+
throw new Error(ERROR_MESSAGES.REQUEST_FAILED('deleteResourceAttributes', err.status, err.message));
|
|
105
|
+
}
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
61
108
|
}
|
|
62
109
|
/**
|
|
63
110
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
@@ -67,8 +114,8 @@ class AuthorizationAttributesService {
|
|
|
67
114
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
68
115
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
69
116
|
* */
|
|
70
|
-
|
|
71
|
-
const topicArn = this.
|
|
117
|
+
async updateResourceAttributesAsync(accountId, appName, callerActionIdentifier, resourceAttributeOperations) {
|
|
118
|
+
const topicArn = this.snsArn;
|
|
72
119
|
const sendToSnsPromises = [];
|
|
73
120
|
const operationChucks = chunk(resourceAttributeOperations, ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE);
|
|
74
121
|
for (const operationsChunk of operationChucks) {
|
|
@@ -76,7 +123,7 @@ class AuthorizationAttributesService {
|
|
|
76
123
|
}
|
|
77
124
|
return (await Promise.all(sendToSnsPromises)).flat();
|
|
78
125
|
}
|
|
79
|
-
|
|
126
|
+
async sendSingleSnsMessage(topicArn, accountId, appName, callerActionIdentifier, operations) {
|
|
80
127
|
const payload = {
|
|
81
128
|
kind: RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND,
|
|
82
129
|
payload: {
|
|
@@ -91,7 +138,7 @@ class AuthorizationAttributesService {
|
|
|
91
138
|
return operations;
|
|
92
139
|
}
|
|
93
140
|
catch (error) {
|
|
94
|
-
logger.error({ error, tag:
|
|
141
|
+
logger.error({ error, tag: AuthorizationAttributesService.LOG_TAG }, 'Authorization resource attributes async update: failed to send operations to SNS');
|
|
95
142
|
return [];
|
|
96
143
|
}
|
|
97
144
|
}
|
|
@@ -107,9 +154,6 @@ class AuthorizationAttributesService {
|
|
|
107
154
|
}
|
|
108
155
|
throw new Error('Unable to get sns topic arn from env variable');
|
|
109
156
|
}
|
|
110
|
-
static getResourceAttributesUrl(accountId) {
|
|
111
|
-
return `${process.env.AUTHORIZATION_URL}/attributes/${accountId}/resource`;
|
|
112
|
-
}
|
|
113
157
|
/**
|
|
114
158
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
115
159
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -118,18 +162,18 @@ class AuthorizationAttributesService {
|
|
|
118
162
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
119
163
|
* @return {Promise<boolean>} - true if succeeded
|
|
120
164
|
*/
|
|
121
|
-
|
|
165
|
+
async asyncResourceAttributesHealthCheck() {
|
|
122
166
|
try {
|
|
123
|
-
const requestedTopicArn = this.
|
|
167
|
+
const requestedTopicArn = this.snsArn;
|
|
124
168
|
const attributes = await getTopicAttributes(requestedTopicArn);
|
|
125
169
|
const isHealthy = !(!attributes || !('TopicArn' in attributes) || attributes.TopicArn !== requestedTopicArn);
|
|
126
170
|
if (!isHealthy) {
|
|
127
|
-
logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag:
|
|
171
|
+
logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag: AuthorizationAttributesService.LOG_TAG }, 'authorization-attributes-service failed in health check');
|
|
128
172
|
}
|
|
129
173
|
return isHealthy;
|
|
130
174
|
}
|
|
131
175
|
catch (error) {
|
|
132
|
-
logger.error({ error, tag:
|
|
176
|
+
logger.error({ error, tag: AuthorizationAttributesService.LOG_TAG }, 'authorization-attributes-service got error during health check');
|
|
133
177
|
return false;
|
|
134
178
|
}
|
|
135
179
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RecursivePartial } from "@mondaydotcomorg/monday-fetch-api";
|
|
2
|
+
import { FetcherConfig } from "@mondaydotcomorg/trident-backend-api";
|
|
3
|
+
export declare const APP_NAME = "authorization";
|
|
4
|
+
export declare const ERROR_MESSAGES: {
|
|
5
|
+
readonly HTTP_CLIENT_NOT_INITIALIZED: "MondayAuthorization: HTTP client is not initialized";
|
|
6
|
+
readonly REQUEST_FAILED: (method: string, status: number, reason: string) => string;
|
|
7
|
+
};
|
|
8
|
+
export declare const DEFAULT_FETCH_OPTIONS: RecursivePartial<FetcherConfig>;
|
|
9
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAUjE,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const APP_NAME = 'authorization';
|
|
2
|
+
const ERROR_MESSAGES = {
|
|
3
|
+
HTTP_CLIENT_NOT_INITIALIZED: 'MondayAuthorization: HTTP client is not initialized',
|
|
4
|
+
REQUEST_FAILED: (method, status, reason) => `MondayAuthorization: [${method}] request failed with status ${status} with reason: ${reason}`,
|
|
5
|
+
};
|
|
6
|
+
const DEFAULT_FETCH_OPTIONS = {
|
|
7
|
+
retryPolicy: {
|
|
8
|
+
useRetries: true,
|
|
9
|
+
maxRetries: 3,
|
|
10
|
+
retryDelayMS: 10,
|
|
11
|
+
},
|
|
12
|
+
logPolicy: {
|
|
13
|
+
logErrors: 'error',
|
|
14
|
+
logRequests: 'info',
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { APP_NAME, DEFAULT_FETCH_OPTIONS, ERROR_MESSAGES };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { FetcherConfig, HttpClient } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
+
import { RecursivePartial } from '@mondaydotcomorg/monday-fetch-api';
|
|
3
|
+
import { CustomRole, RolesResponse, RoleUpdate } from './types/roles';
|
|
4
|
+
export declare class CustomRoles {
|
|
5
|
+
private httpClient;
|
|
6
|
+
private fetchOptions;
|
|
7
|
+
private attributionHeaders;
|
|
8
|
+
/**
|
|
9
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
10
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
11
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
12
|
+
*/
|
|
13
|
+
constructor(httpClient?: HttpClient, fetchOptions?: RecursivePartial<FetcherConfig>);
|
|
14
|
+
/**
|
|
15
|
+
* Get all roles for an account
|
|
16
|
+
* @param accountId - The account ID
|
|
17
|
+
* @returns - The roles for the account, both basic and custom roles. Note that basic role ids are returned in A style and not B style.
|
|
18
|
+
*/
|
|
19
|
+
getRoles(accountId: number, resourceTypes: string[]): Promise<RolesResponse>;
|
|
20
|
+
createCustomRole(accountId: number, roles: CustomRole[]): Promise<RolesResponse>;
|
|
21
|
+
deleteCustomRole(accountId: number, roleIds: number[]): Promise<RolesResponse>;
|
|
22
|
+
updateCustomRole(accountId: number, updateRequests: RoleUpdate[]): Promise<RolesResponse>;
|
|
23
|
+
private sendRoleRequest;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,aAAa,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACtF,OAAO,EAAoB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAEvF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMpE,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,kBAAkB,CAA4B;IAEtD;;;;OAIG;gBACS,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAqBnF;;;;OAIG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAI5E,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBhF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAM9E,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;YAMjF,eAAe;CA2B9B"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Api } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
+
import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
|
|
3
|
+
import { ERROR_MESSAGES, DEFAULT_FETCH_OPTIONS, APP_NAME } from './constants.mjs';
|
|
4
|
+
import { getAttributionsFromApi } from './attributions-service.mjs';
|
|
5
|
+
|
|
6
|
+
const API_PATH = '/roles/account/{accountId}';
|
|
7
|
+
const A_STYLE_NAME = 'A';
|
|
8
|
+
class CustomRoles {
|
|
9
|
+
httpClient;
|
|
10
|
+
fetchOptions;
|
|
11
|
+
attributionHeaders;
|
|
12
|
+
/**
|
|
13
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
14
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
15
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
16
|
+
*/
|
|
17
|
+
constructor(httpClient, fetchOptions) {
|
|
18
|
+
if (!httpClient) {
|
|
19
|
+
httpClient = Api.getPart('httpClient');
|
|
20
|
+
if (!httpClient) {
|
|
21
|
+
throw new Error(ERROR_MESSAGES.HTTP_CLIENT_NOT_INITIALIZED);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!fetchOptions) {
|
|
25
|
+
fetchOptions = DEFAULT_FETCH_OPTIONS;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
fetchOptions = {
|
|
29
|
+
...DEFAULT_FETCH_OPTIONS,
|
|
30
|
+
...fetchOptions,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
this.httpClient = httpClient;
|
|
34
|
+
this.fetchOptions = fetchOptions;
|
|
35
|
+
this.attributionHeaders = getAttributionsFromApi();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get all roles for an account
|
|
39
|
+
* @param accountId - The account ID
|
|
40
|
+
* @returns - The roles for the account, both basic and custom roles. Note that basic role ids are returned in A style and not B style.
|
|
41
|
+
*/
|
|
42
|
+
async getRoles(accountId, resourceTypes) {
|
|
43
|
+
return await this.sendRoleRequest('GET', accountId, { resourceTypes: resourceTypes.join(',') });
|
|
44
|
+
}
|
|
45
|
+
async createCustomRole(accountId, roles) {
|
|
46
|
+
if (roles.length === 0) {
|
|
47
|
+
throw new Error('Roles array cannot be empty');
|
|
48
|
+
}
|
|
49
|
+
const serializedRoles = roles.map(role => ({
|
|
50
|
+
"name": role.name,
|
|
51
|
+
"resourceType": role.resourceType,
|
|
52
|
+
"resourceId": role.resourceId,
|
|
53
|
+
"sourceRole": {
|
|
54
|
+
"id": role.basicRoleId,
|
|
55
|
+
"type": role.basicRoleType,
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
return await this.sendRoleRequest('PUT', accountId, {
|
|
59
|
+
customRoles: serializedRoles,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async deleteCustomRole(accountId, roleIds) {
|
|
63
|
+
return await this.sendRoleRequest('DELETE', accountId, {
|
|
64
|
+
ids: roleIds,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async updateCustomRole(accountId, updateRequests) {
|
|
68
|
+
return await this.sendRoleRequest('PATCH', accountId, {
|
|
69
|
+
customRoles: updateRequests,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async sendRoleRequest(method, accountId, body) {
|
|
73
|
+
try {
|
|
74
|
+
return await this.httpClient.fetch({
|
|
75
|
+
url: {
|
|
76
|
+
appName: APP_NAME,
|
|
77
|
+
path: API_PATH.replace('{accountId}', accountId.toString()),
|
|
78
|
+
},
|
|
79
|
+
query: {
|
|
80
|
+
style: A_STYLE_NAME,
|
|
81
|
+
},
|
|
82
|
+
method,
|
|
83
|
+
headers: {
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
...this.attributionHeaders,
|
|
86
|
+
},
|
|
87
|
+
body: body ? body : undefined,
|
|
88
|
+
}, this.fetchOptions);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
if (err instanceof HttpFetcherError) {
|
|
92
|
+
throw new Error(ERROR_MESSAGES.REQUEST_FAILED('sendRoleRequest', err.status, err.message));
|
|
93
|
+
}
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { CustomRoles };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface CustomRole {
|
|
2
|
+
id?: number;
|
|
3
|
+
name: string;
|
|
4
|
+
resourceType: string;
|
|
5
|
+
resourceId: number;
|
|
6
|
+
basicRoleId: number;
|
|
7
|
+
basicRoleType: RoleType;
|
|
8
|
+
}
|
|
9
|
+
export interface BasicRole {
|
|
10
|
+
id: number;
|
|
11
|
+
resourceType: string;
|
|
12
|
+
roleType: string;
|
|
13
|
+
name: string;
|
|
14
|
+
}
|
|
15
|
+
export interface RolesResponse {
|
|
16
|
+
customRoles: CustomRole[];
|
|
17
|
+
basicRoles?: BasicRole[];
|
|
18
|
+
}
|
|
19
|
+
export declare enum RoleType {
|
|
20
|
+
CUSTOM = "custom_role",
|
|
21
|
+
BASIC = "basic_role"
|
|
22
|
+
}
|
|
23
|
+
export interface RoleUpdate {
|
|
24
|
+
id: number;
|
|
25
|
+
updatedAttributes: {
|
|
26
|
+
name: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../../src/types/roles.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,QAAQ,CAAA;CAC1B;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC5B;AAED,oBAAY,QAAQ;IAChB,MAAM,gBAAgB;IACtB,KAAK,eAAe;CACvB;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;KAChB,CAAA;CACJ"}
|
package/dist/roles.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { FetcherConfig, HttpClient } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
+
import { RecursivePartial } from '@mondaydotcomorg/monday-fetch-api';
|
|
3
|
+
import { CustomRole, RolesResponse, RoleUpdate } from './types/roles';
|
|
4
|
+
export declare class CustomRoles {
|
|
5
|
+
private httpClient;
|
|
6
|
+
private fetchOptions;
|
|
7
|
+
private attributionHeaders;
|
|
8
|
+
/**
|
|
9
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
10
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
11
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
12
|
+
*/
|
|
13
|
+
constructor(httpClient?: HttpClient, fetchOptions?: RecursivePartial<FetcherConfig>);
|
|
14
|
+
/**
|
|
15
|
+
* Get all roles for an account
|
|
16
|
+
* @param accountId - The account ID
|
|
17
|
+
* @returns - The roles for the account, both basic and custom roles. Note that basic role ids are returned in A style and not B style.
|
|
18
|
+
*/
|
|
19
|
+
getRoles(accountId: number, resourceTypes: string[]): Promise<RolesResponse>;
|
|
20
|
+
createCustomRole(accountId: number, roles: CustomRole[]): Promise<RolesResponse>;
|
|
21
|
+
deleteCustomRole(accountId: number, roleIds: number[]): Promise<RolesResponse>;
|
|
22
|
+
updateCustomRole(accountId: number, updateRequests: RoleUpdate[]): Promise<RolesResponse>;
|
|
23
|
+
private sendRoleRequest;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,aAAa,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACtF,OAAO,EAAoB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAEvF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMpE,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,kBAAkB,CAA4B;IAEtD;;;;OAIG;gBACS,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAqBnF;;;;OAIG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAI5E,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBhF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAM9E,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;YAMjF,eAAe;CA2B9B"}
|
package/dist/roles.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const tridentBackendApi = require('@mondaydotcomorg/trident-backend-api');
|
|
4
|
+
const mondayFetchApi = require('@mondaydotcomorg/monday-fetch-api');
|
|
5
|
+
const constants = require('./constants.js');
|
|
6
|
+
const attributionsService = require('./attributions-service.js');
|
|
7
|
+
|
|
8
|
+
const API_PATH = '/roles/account/{accountId}';
|
|
9
|
+
const A_STYLE_NAME = 'A';
|
|
10
|
+
class CustomRoles {
|
|
11
|
+
httpClient;
|
|
12
|
+
fetchOptions;
|
|
13
|
+
attributionHeaders;
|
|
14
|
+
/**
|
|
15
|
+
* Public constructor to create the AuthorizationAttributesService instance.
|
|
16
|
+
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
17
|
+
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
18
|
+
*/
|
|
19
|
+
constructor(httpClient, fetchOptions) {
|
|
20
|
+
if (!httpClient) {
|
|
21
|
+
httpClient = tridentBackendApi.Api.getPart('httpClient');
|
|
22
|
+
if (!httpClient) {
|
|
23
|
+
throw new Error(constants.ERROR_MESSAGES.HTTP_CLIENT_NOT_INITIALIZED);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (!fetchOptions) {
|
|
27
|
+
fetchOptions = constants.DEFAULT_FETCH_OPTIONS;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
fetchOptions = {
|
|
31
|
+
...constants.DEFAULT_FETCH_OPTIONS,
|
|
32
|
+
...fetchOptions,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
this.httpClient = httpClient;
|
|
36
|
+
this.fetchOptions = fetchOptions;
|
|
37
|
+
this.attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get all roles for an account
|
|
41
|
+
* @param accountId - The account ID
|
|
42
|
+
* @returns - The roles for the account, both basic and custom roles. Note that basic role ids are returned in A style and not B style.
|
|
43
|
+
*/
|
|
44
|
+
async getRoles(accountId, resourceTypes) {
|
|
45
|
+
return await this.sendRoleRequest('GET', accountId, { resourceTypes: resourceTypes.join(',') });
|
|
46
|
+
}
|
|
47
|
+
async createCustomRole(accountId, roles) {
|
|
48
|
+
if (roles.length === 0) {
|
|
49
|
+
throw new Error('Roles array cannot be empty');
|
|
50
|
+
}
|
|
51
|
+
const serializedRoles = roles.map(role => ({
|
|
52
|
+
"name": role.name,
|
|
53
|
+
"resourceType": role.resourceType,
|
|
54
|
+
"resourceId": role.resourceId,
|
|
55
|
+
"sourceRole": {
|
|
56
|
+
"id": role.basicRoleId,
|
|
57
|
+
"type": role.basicRoleType,
|
|
58
|
+
}
|
|
59
|
+
}));
|
|
60
|
+
return await this.sendRoleRequest('PUT', accountId, {
|
|
61
|
+
customRoles: serializedRoles,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async deleteCustomRole(accountId, roleIds) {
|
|
65
|
+
return await this.sendRoleRequest('DELETE', accountId, {
|
|
66
|
+
ids: roleIds,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async updateCustomRole(accountId, updateRequests) {
|
|
70
|
+
return await this.sendRoleRequest('PATCH', accountId, {
|
|
71
|
+
customRoles: updateRequests,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async sendRoleRequest(method, accountId, body) {
|
|
75
|
+
try {
|
|
76
|
+
return await this.httpClient.fetch({
|
|
77
|
+
url: {
|
|
78
|
+
appName: constants.APP_NAME,
|
|
79
|
+
path: API_PATH.replace('{accountId}', accountId.toString()),
|
|
80
|
+
},
|
|
81
|
+
query: {
|
|
82
|
+
style: A_STYLE_NAME,
|
|
83
|
+
},
|
|
84
|
+
method,
|
|
85
|
+
headers: {
|
|
86
|
+
'Content-Type': 'application/json',
|
|
87
|
+
...this.attributionHeaders,
|
|
88
|
+
},
|
|
89
|
+
body: body ? body : undefined,
|
|
90
|
+
}, this.fetchOptions);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
94
|
+
throw new Error(constants.ERROR_MESSAGES.REQUEST_FAILED('sendRoleRequest', err.status, err.message));
|
|
95
|
+
}
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
exports.CustomRoles = CustomRoles;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface CustomRole {
|
|
2
|
+
id?: number;
|
|
3
|
+
name: string;
|
|
4
|
+
resourceType: string;
|
|
5
|
+
resourceId: number;
|
|
6
|
+
basicRoleId: number;
|
|
7
|
+
basicRoleType: RoleType;
|
|
8
|
+
}
|
|
9
|
+
export interface BasicRole {
|
|
10
|
+
id: number;
|
|
11
|
+
resourceType: string;
|
|
12
|
+
roleType: string;
|
|
13
|
+
name: string;
|
|
14
|
+
}
|
|
15
|
+
export interface RolesResponse {
|
|
16
|
+
customRoles: CustomRole[];
|
|
17
|
+
basicRoles?: BasicRole[];
|
|
18
|
+
}
|
|
19
|
+
export declare enum RoleType {
|
|
20
|
+
CUSTOM = "custom_role",
|
|
21
|
+
BASIC = "basic_role"
|
|
22
|
+
}
|
|
23
|
+
export interface RoleUpdate {
|
|
24
|
+
id: number;
|
|
25
|
+
updatedAttributes: {
|
|
26
|
+
name: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/types/roles.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,QAAQ,CAAA;CAC1B;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC5B;AAED,oBAAY,QAAQ;IAChB,MAAM,gBAAgB;IACtB,KAAK,eAAe;CACvB;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;KAChB,CAAA;CACJ"}
|