@mondaydotcomorg/monday-authorization 2.1.1-feature-bashanye-remove-authorization-url-secret-usage.04a9d3c → 2.1.1
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 +8 -17
- package/dist/authorization-attributes-service.d.ts.map +1 -1
- package/dist/authorization-attributes-service.js +45 -99
- package/dist/esm/authorization-attributes-service.d.ts +8 -17
- package/dist/esm/authorization-attributes-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-service.mjs +46 -100
- package/package.json +1 -1
- package/dist/constants.d.ts +0 -6
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -10
- package/dist/esm/constants.d.ts +0 -6
- package/dist/esm/constants.d.ts.map +0 -1
- package/dist/esm/constants.mjs +0 -7
|
@@ -1,35 +1,25 @@
|
|
|
1
|
-
import { FetcherConfig, HttpClient } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
-
import { RecursivePartial } from '@mondaydotcomorg/monday-fetch-api';
|
|
3
1
|
import { ResourceAttributeAssignment, ResourceAttributeResponse, ResourceAttributesOperation } from './types/authorization-attributes-contracts';
|
|
4
2
|
import { Resource } from './types/general';
|
|
5
3
|
export declare class AuthorizationAttributesService {
|
|
6
4
|
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>);
|
|
17
5
|
/**
|
|
18
6
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
19
7
|
* @param accountId
|
|
8
|
+
* @param userId
|
|
20
9
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
21
10
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
22
11
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
23
12
|
*/
|
|
24
|
-
upsertResourceAttributes(accountId: number, resourceAttributeAssignments: ResourceAttributeAssignment[]): Promise<ResourceAttributeResponse>;
|
|
13
|
+
static upsertResourceAttributes(accountId: number, userId: number, resourceAttributeAssignments: ResourceAttributeAssignment[]): Promise<ResourceAttributeResponse>;
|
|
25
14
|
/**
|
|
26
15
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
27
16
|
* @param accountId
|
|
17
|
+
* @param userId
|
|
28
18
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
29
19
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
30
20
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
31
21
|
*/
|
|
32
|
-
deleteResourceAttributes(accountId: number, resource: Resource, attributeKeys: string[]): Promise<ResourceAttributeResponse>;
|
|
22
|
+
static deleteResourceAttributes(accountId: number, userId: number, resource: Resource, attributeKeys: string[]): Promise<ResourceAttributeResponse>;
|
|
33
23
|
/**
|
|
34
24
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
35
25
|
* @param accountId
|
|
@@ -38,9 +28,10 @@ export declare class AuthorizationAttributesService {
|
|
|
38
28
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
39
29
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
40
30
|
* */
|
|
41
|
-
updateResourceAttributesAsync(accountId: number, appName: string, callerActionIdentifier: string, resourceAttributeOperations: ResourceAttributesOperation[]): Promise<ResourceAttributesOperation[]>;
|
|
42
|
-
private sendSingleSnsMessage;
|
|
31
|
+
static updateResourceAttributesAsync(accountId: number, appName: string, callerActionIdentifier: string, resourceAttributeOperations: ResourceAttributesOperation[]): Promise<ResourceAttributesOperation[]>;
|
|
32
|
+
private static sendSingleSnsMessage;
|
|
43
33
|
private static getSnsTopicArn;
|
|
34
|
+
private static getResourceAttributesUrl;
|
|
44
35
|
/**
|
|
45
36
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
46
37
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -49,6 +40,6 @@ export declare class AuthorizationAttributesService {
|
|
|
49
40
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
50
41
|
* @return {Promise<boolean>} - true if succeeded
|
|
51
42
|
*/
|
|
52
|
-
asyncResourceAttributesHealthCheck(): Promise<boolean>;
|
|
43
|
+
static asyncResourceAttributesHealthCheck(): Promise<boolean>;
|
|
53
44
|
}
|
|
54
45
|
//# 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":"AAIA,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAU3C,qBAAa,8BAA8B;IACzC,OAAO,CAAC,MAAM,CAAC,OAAO,CAA8B;IACpD;;;;;;;OAOG;WACU,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,4BAA4B,EAAE,2BAA2B,EAAE,GAC1D,OAAO,CAAC,yBAAyB,CAAC;IAwBrC;;;;;;;OAOG;WACU,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,yBAAyB,CAAC;IAyBrC;;;;;;;UAOM;WACO,6BAA6B,CACxC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,sBAAsB,EAAE,MAAM,EAC9B,2BAA2B,EAAE,2BAA2B,EAAE,GACzD,OAAO,CAAC,2BAA2B,EAAE,CAAC;mBAYpB,oBAAoB;IA4BzC,OAAO,CAAC,MAAM,CAAC,cAAc;IAe7B,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAIvC;;;;;;;OAOG;WACU,kCAAkC,IAAI,OAAO,CAAC,OAAO,CAAC;CAiBpE"}
|
|
@@ -1,126 +1,69 @@
|
|
|
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');
|
|
4
5
|
const tridentBackendApi = require('@mondaydotcomorg/trident-backend-api');
|
|
5
6
|
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');
|
|
11
10
|
|
|
12
11
|
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
13
12
|
|
|
14
13
|
const chunk__default = /*#__PURE__*/_interopDefault(chunk);
|
|
15
14
|
|
|
16
|
-
function getDefaultFetchOptions() {
|
|
17
|
-
return {
|
|
18
|
-
retryPolicy: {
|
|
19
|
-
useRetries: true,
|
|
20
|
-
maxRetries: 3,
|
|
21
|
-
retryDelayMS: 10,
|
|
22
|
-
},
|
|
23
|
-
logPolicy: {
|
|
24
|
-
logErrors: 'error',
|
|
25
|
-
logRequests: 'info',
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
15
|
class AuthorizationAttributesService {
|
|
30
16
|
static LOG_TAG = 'authorization_attributes';
|
|
31
|
-
static API_PATHS = {
|
|
32
|
-
UPSERT_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource',
|
|
33
|
-
DELETE_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource/{resourceType}/{resourceId}',
|
|
34
|
-
};
|
|
35
|
-
httpClient;
|
|
36
|
-
fetchOptions;
|
|
37
|
-
snsArn;
|
|
38
|
-
/**
|
|
39
|
-
* Public constructor to create the AuthorizationAttributesService instance.
|
|
40
|
-
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
41
|
-
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
42
|
-
*/
|
|
43
|
-
constructor(httpClient, fetchOptions) {
|
|
44
|
-
if (!httpClient) {
|
|
45
|
-
httpClient = tridentBackendApi.Api.getPart('httpClient');
|
|
46
|
-
if (!httpClient) {
|
|
47
|
-
throw new Error(constants.ERROR_MESSAGES.HTTP_CLIENT_NOT_INITIALIZED);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (!fetchOptions) {
|
|
51
|
-
fetchOptions = getDefaultFetchOptions();
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
fetchOptions = {
|
|
55
|
-
...getDefaultFetchOptions(),
|
|
56
|
-
...fetchOptions,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
this.httpClient = httpClient;
|
|
60
|
-
this.fetchOptions = fetchOptions;
|
|
61
|
-
this.snsArn = AuthorizationAttributesService.getSnsTopicArn();
|
|
62
|
-
}
|
|
63
17
|
/**
|
|
64
18
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
65
19
|
* @param accountId
|
|
20
|
+
* @param userId
|
|
66
21
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
67
22
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
68
23
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
69
24
|
*/
|
|
70
|
-
async upsertResourceAttributes(accountId, resourceAttributeAssignments) {
|
|
25
|
+
static async upsertResourceAttributes(accountId, userId, resourceAttributeAssignments) {
|
|
26
|
+
const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
71
27
|
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
88
|
-
throw new Error(constants.ERROR_MESSAGES.REQUEST_FAILED('upsertResourceAttributes', err.status, err.message));
|
|
89
|
-
}
|
|
90
|
-
throw err;
|
|
91
|
-
}
|
|
28
|
+
const response = await mondayFetch.fetch(this.getResourceAttributesUrl(accountId), {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: {
|
|
31
|
+
Authorization: internalAuthToken,
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
...attributionHeaders,
|
|
34
|
+
},
|
|
35
|
+
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
36
|
+
body: JSON.stringify({ resourceAttributeAssignments }),
|
|
37
|
+
}, authorizationInternalService.AuthorizationInternalService.getRequestFetchOptions());
|
|
38
|
+
const responseBody = await response.json();
|
|
39
|
+
authorizationInternalService.AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'upsertResourceAttributesSync');
|
|
40
|
+
return { attributes: responseBody['attributes'] };
|
|
92
41
|
}
|
|
93
42
|
/**
|
|
94
43
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
95
44
|
* @param accountId
|
|
45
|
+
* @param userId
|
|
96
46
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
97
47
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
98
48
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
99
49
|
*/
|
|
100
|
-
async deleteResourceAttributes(accountId, resource, attributeKeys) {
|
|
50
|
+
static async deleteResourceAttributes(accountId, userId, resource, attributeKeys) {
|
|
51
|
+
const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
52
|
+
const url = `${this.getResourceAttributesUrl(accountId)}/${resource.type}/${resource.id}`;
|
|
101
53
|
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
body: JSON.stringify({ keys: attributeKeys }),
|
|
116
|
-
}, this.fetchOptions);
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
120
|
-
throw new Error(constants.ERROR_MESSAGES.REQUEST_FAILED('deleteResourceAttributes', err.status, err.message));
|
|
121
|
-
}
|
|
122
|
-
throw err;
|
|
123
|
-
}
|
|
54
|
+
const response = await mondayFetch.fetch(url, {
|
|
55
|
+
method: 'DELETE',
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: internalAuthToken,
|
|
58
|
+
'Content-Type': 'application/json',
|
|
59
|
+
...attributionHeaders,
|
|
60
|
+
},
|
|
61
|
+
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
62
|
+
body: JSON.stringify({ keys: attributeKeys }),
|
|
63
|
+
}, authorizationInternalService.AuthorizationInternalService.getRequestFetchOptions());
|
|
64
|
+
const responseBody = await response.json();
|
|
65
|
+
authorizationInternalService.AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'deleteResourceAttributesSync');
|
|
66
|
+
return { attributes: responseBody['attributes'] };
|
|
124
67
|
}
|
|
125
68
|
/**
|
|
126
69
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
@@ -130,8 +73,8 @@ class AuthorizationAttributesService {
|
|
|
130
73
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
131
74
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
132
75
|
* */
|
|
133
|
-
async updateResourceAttributesAsync(accountId, appName, callerActionIdentifier, resourceAttributeOperations) {
|
|
134
|
-
const topicArn = this.
|
|
76
|
+
static async updateResourceAttributesAsync(accountId, appName, callerActionIdentifier, resourceAttributeOperations) {
|
|
77
|
+
const topicArn = this.getSnsTopicArn();
|
|
135
78
|
const sendToSnsPromises = [];
|
|
136
79
|
const operationChucks = chunk__default.default(resourceAttributeOperations, constants_sns.ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE);
|
|
137
80
|
for (const operationsChunk of operationChucks) {
|
|
@@ -139,7 +82,7 @@ class AuthorizationAttributesService {
|
|
|
139
82
|
}
|
|
140
83
|
return (await Promise.all(sendToSnsPromises)).flat();
|
|
141
84
|
}
|
|
142
|
-
async sendSingleSnsMessage(topicArn, accountId, appName, callerActionIdentifier, operations) {
|
|
85
|
+
static async sendSingleSnsMessage(topicArn, accountId, appName, callerActionIdentifier, operations) {
|
|
143
86
|
const payload = {
|
|
144
87
|
kind: constants_sns.RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND,
|
|
145
88
|
payload: {
|
|
@@ -154,7 +97,7 @@ class AuthorizationAttributesService {
|
|
|
154
97
|
return operations;
|
|
155
98
|
}
|
|
156
99
|
catch (error) {
|
|
157
|
-
authorizationInternalService.logger.error({ error, tag:
|
|
100
|
+
authorizationInternalService.logger.error({ error, tag: this.LOG_TAG }, 'Authorization resource attributes async update: failed to send operations to SNS');
|
|
158
101
|
return [];
|
|
159
102
|
}
|
|
160
103
|
}
|
|
@@ -170,6 +113,9 @@ class AuthorizationAttributesService {
|
|
|
170
113
|
}
|
|
171
114
|
throw new Error('Unable to get sns topic arn from env variable');
|
|
172
115
|
}
|
|
116
|
+
static getResourceAttributesUrl(accountId) {
|
|
117
|
+
return `${process.env.AUTHORIZATION_URL}/attributes/${accountId}/resource`;
|
|
118
|
+
}
|
|
173
119
|
/**
|
|
174
120
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
175
121
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -178,18 +124,18 @@ class AuthorizationAttributesService {
|
|
|
178
124
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
179
125
|
* @return {Promise<boolean>} - true if succeeded
|
|
180
126
|
*/
|
|
181
|
-
async asyncResourceAttributesHealthCheck() {
|
|
127
|
+
static async asyncResourceAttributesHealthCheck() {
|
|
182
128
|
try {
|
|
183
|
-
const requestedTopicArn = this.
|
|
129
|
+
const requestedTopicArn = this.getSnsTopicArn();
|
|
184
130
|
const attributes = await mondaySns.getTopicAttributes(requestedTopicArn);
|
|
185
131
|
const isHealthy = !(!attributes || !('TopicArn' in attributes) || attributes.TopicArn !== requestedTopicArn);
|
|
186
132
|
if (!isHealthy) {
|
|
187
|
-
authorizationInternalService.logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag:
|
|
133
|
+
authorizationInternalService.logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag: this.LOG_TAG }, 'authorization-attributes-service failed in health check');
|
|
188
134
|
}
|
|
189
135
|
return isHealthy;
|
|
190
136
|
}
|
|
191
137
|
catch (error) {
|
|
192
|
-
authorizationInternalService.logger.error({ error, tag:
|
|
138
|
+
authorizationInternalService.logger.error({ error, tag: this.LOG_TAG }, 'authorization-attributes-service got error during health check');
|
|
193
139
|
return false;
|
|
194
140
|
}
|
|
195
141
|
}
|
|
@@ -1,35 +1,25 @@
|
|
|
1
|
-
import { FetcherConfig, HttpClient } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
-
import { RecursivePartial } from '@mondaydotcomorg/monday-fetch-api';
|
|
3
1
|
import { ResourceAttributeAssignment, ResourceAttributeResponse, ResourceAttributesOperation } from './types/authorization-attributes-contracts';
|
|
4
2
|
import { Resource } from './types/general';
|
|
5
3
|
export declare class AuthorizationAttributesService {
|
|
6
4
|
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>);
|
|
17
5
|
/**
|
|
18
6
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
19
7
|
* @param accountId
|
|
8
|
+
* @param userId
|
|
20
9
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
21
10
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
22
11
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
23
12
|
*/
|
|
24
|
-
upsertResourceAttributes(accountId: number, resourceAttributeAssignments: ResourceAttributeAssignment[]): Promise<ResourceAttributeResponse>;
|
|
13
|
+
static upsertResourceAttributes(accountId: number, userId: number, resourceAttributeAssignments: ResourceAttributeAssignment[]): Promise<ResourceAttributeResponse>;
|
|
25
14
|
/**
|
|
26
15
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
27
16
|
* @param accountId
|
|
17
|
+
* @param userId
|
|
28
18
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
29
19
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
30
20
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
31
21
|
*/
|
|
32
|
-
deleteResourceAttributes(accountId: number, resource: Resource, attributeKeys: string[]): Promise<ResourceAttributeResponse>;
|
|
22
|
+
static deleteResourceAttributes(accountId: number, userId: number, resource: Resource, attributeKeys: string[]): Promise<ResourceAttributeResponse>;
|
|
33
23
|
/**
|
|
34
24
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
35
25
|
* @param accountId
|
|
@@ -38,9 +28,10 @@ export declare class AuthorizationAttributesService {
|
|
|
38
28
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
39
29
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
40
30
|
* */
|
|
41
|
-
updateResourceAttributesAsync(accountId: number, appName: string, callerActionIdentifier: string, resourceAttributeOperations: ResourceAttributesOperation[]): Promise<ResourceAttributesOperation[]>;
|
|
42
|
-
private sendSingleSnsMessage;
|
|
31
|
+
static updateResourceAttributesAsync(accountId: number, appName: string, callerActionIdentifier: string, resourceAttributeOperations: ResourceAttributesOperation[]): Promise<ResourceAttributesOperation[]>;
|
|
32
|
+
private static sendSingleSnsMessage;
|
|
43
33
|
private static getSnsTopicArn;
|
|
34
|
+
private static getResourceAttributesUrl;
|
|
44
35
|
/**
|
|
45
36
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
46
37
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -49,6 +40,6 @@ export declare class AuthorizationAttributesService {
|
|
|
49
40
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
50
41
|
* @return {Promise<boolean>} - true if succeeded
|
|
51
42
|
*/
|
|
52
|
-
asyncResourceAttributesHealthCheck(): Promise<boolean>;
|
|
43
|
+
static asyncResourceAttributesHealthCheck(): Promise<boolean>;
|
|
53
44
|
}
|
|
54
45
|
//# 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":"AAIA,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAU3C,qBAAa,8BAA8B;IACzC,OAAO,CAAC,MAAM,CAAC,OAAO,CAA8B;IACpD;;;;;;;OAOG;WACU,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,4BAA4B,EAAE,2BAA2B,EAAE,GAC1D,OAAO,CAAC,yBAAyB,CAAC;IAwBrC;;;;;;;OAOG;WACU,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,yBAAyB,CAAC;IAyBrC;;;;;;;UAOM;WACO,6BAA6B,CACxC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,sBAAsB,EAAE,MAAM,EAC9B,2BAA2B,EAAE,2BAA2B,EAAE,GACzD,OAAO,CAAC,2BAA2B,EAAE,CAAC;mBAYpB,oBAAoB;IA4BzC,OAAO,CAAC,MAAM,CAAC,cAAc;IAe7B,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAIvC;;;;;;;OAOG;WACU,kCAAkC,IAAI,OAAO,CAAC,OAAO,CAAC;CAiBpE"}
|
|
@@ -1,120 +1,63 @@
|
|
|
1
1
|
import chunk from 'lodash/chunk.js';
|
|
2
|
+
import { fetch } from '@mondaydotcomorg/monday-fetch';
|
|
2
3
|
import { Api } from '@mondaydotcomorg/trident-backend-api';
|
|
3
4
|
import { sendToSns, getTopicAttributes } from '@mondaydotcomorg/monday-sns';
|
|
4
|
-
import {
|
|
5
|
-
import { logger } from './authorization-internal-service.mjs';
|
|
5
|
+
import { AuthorizationInternalService, 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, APP_NAME } from './constants.mjs';
|
|
9
8
|
|
|
10
|
-
function getDefaultFetchOptions() {
|
|
11
|
-
return {
|
|
12
|
-
retryPolicy: {
|
|
13
|
-
useRetries: true,
|
|
14
|
-
maxRetries: 3,
|
|
15
|
-
retryDelayMS: 10,
|
|
16
|
-
},
|
|
17
|
-
logPolicy: {
|
|
18
|
-
logErrors: 'error',
|
|
19
|
-
logRequests: 'info',
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
9
|
class AuthorizationAttributesService {
|
|
24
10
|
static LOG_TAG = 'authorization_attributes';
|
|
25
|
-
static API_PATHS = {
|
|
26
|
-
UPSERT_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource',
|
|
27
|
-
DELETE_RESOURCE_ATTRIBUTES: '/attributes/{accountId}/resource/{resourceType}/{resourceId}',
|
|
28
|
-
};
|
|
29
|
-
httpClient;
|
|
30
|
-
fetchOptions;
|
|
31
|
-
snsArn;
|
|
32
|
-
/**
|
|
33
|
-
* Public constructor to create the AuthorizationAttributesService instance.
|
|
34
|
-
* @param httpClient The HTTP client to use for API requests, if not provided, the default HTTP client from Api will be used.
|
|
35
|
-
* @param fetchOptions The fetch options to use for API requests, if not provided, the default fetch options will be used.
|
|
36
|
-
*/
|
|
37
|
-
constructor(httpClient, fetchOptions) {
|
|
38
|
-
if (!httpClient) {
|
|
39
|
-
httpClient = Api.getPart('httpClient');
|
|
40
|
-
if (!httpClient) {
|
|
41
|
-
throw new Error(ERROR_MESSAGES.HTTP_CLIENT_NOT_INITIALIZED);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (!fetchOptions) {
|
|
45
|
-
fetchOptions = getDefaultFetchOptions();
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
fetchOptions = {
|
|
49
|
-
...getDefaultFetchOptions(),
|
|
50
|
-
...fetchOptions,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
this.httpClient = httpClient;
|
|
54
|
-
this.fetchOptions = fetchOptions;
|
|
55
|
-
this.snsArn = AuthorizationAttributesService.getSnsTopicArn();
|
|
56
|
-
}
|
|
57
11
|
/**
|
|
58
12
|
* Upsert resource attributes synchronously, performing http call to the authorization MS to assign the given attributes to the given resource.
|
|
59
13
|
* @param accountId
|
|
14
|
+
* @param userId
|
|
60
15
|
* @param resourceAttributeAssignments - Array of resource (resourceType, resourceId) and attribute (key, value) pairs to upsert in the authorization MS.
|
|
61
16
|
* e.g. [{ resourceType: 'board', resourceId: 123, key: 'board_kind', value: 'private' }]
|
|
62
17
|
* @returns ResourceAttributeResponse - The affected (created and updated_ resource attributes assignments in the `attributes` field.
|
|
63
18
|
*/
|
|
64
|
-
async upsertResourceAttributes(accountId, resourceAttributeAssignments) {
|
|
19
|
+
static async upsertResourceAttributes(accountId, userId, resourceAttributeAssignments) {
|
|
20
|
+
const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
65
21
|
const attributionHeaders = getAttributionsFromApi();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
catch (err) {
|
|
81
|
-
if (err instanceof HttpFetcherError) {
|
|
82
|
-
throw new Error(ERROR_MESSAGES.REQUEST_FAILED('upsertResourceAttributes', err.status, err.message));
|
|
83
|
-
}
|
|
84
|
-
throw err;
|
|
85
|
-
}
|
|
22
|
+
const response = await fetch(this.getResourceAttributesUrl(accountId), {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: internalAuthToken,
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
...attributionHeaders,
|
|
28
|
+
},
|
|
29
|
+
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
30
|
+
body: JSON.stringify({ resourceAttributeAssignments }),
|
|
31
|
+
}, AuthorizationInternalService.getRequestFetchOptions());
|
|
32
|
+
const responseBody = await response.json();
|
|
33
|
+
AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'upsertResourceAttributesSync');
|
|
34
|
+
return { attributes: responseBody['attributes'] };
|
|
86
35
|
}
|
|
87
36
|
/**
|
|
88
37
|
* Delete resource attributes assignments synchronously, performing http call to the authorization MS to delete the given attributes from the given singular resource.
|
|
89
38
|
* @param accountId
|
|
39
|
+
* @param userId
|
|
90
40
|
* @param resource - The resource (resourceType, resourceId) to delete the attributes for.
|
|
91
41
|
* @param attributeKeys - Array of attribute keys to delete for the resource.
|
|
92
42
|
* @returns ResourceAttributeResponse - The affected (deleted) resource attributes assignments in the `attributes` field.
|
|
93
43
|
*/
|
|
94
|
-
async deleteResourceAttributes(accountId, resource, attributeKeys) {
|
|
44
|
+
static async deleteResourceAttributes(accountId, userId, resource, attributeKeys) {
|
|
45
|
+
const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
46
|
+
const url = `${this.getResourceAttributesUrl(accountId)}/${resource.type}/${resource.id}`;
|
|
95
47
|
const attributionHeaders = getAttributionsFromApi();
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
body: JSON.stringify({ keys: attributeKeys }),
|
|
110
|
-
}, this.fetchOptions);
|
|
111
|
-
}
|
|
112
|
-
catch (err) {
|
|
113
|
-
if (err instanceof HttpFetcherError) {
|
|
114
|
-
throw new Error(ERROR_MESSAGES.REQUEST_FAILED('deleteResourceAttributes', err.status, err.message));
|
|
115
|
-
}
|
|
116
|
-
throw err;
|
|
117
|
-
}
|
|
48
|
+
const response = await fetch(url, {
|
|
49
|
+
method: 'DELETE',
|
|
50
|
+
headers: {
|
|
51
|
+
Authorization: internalAuthToken,
|
|
52
|
+
'Content-Type': 'application/json',
|
|
53
|
+
...attributionHeaders,
|
|
54
|
+
},
|
|
55
|
+
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
56
|
+
body: JSON.stringify({ keys: attributeKeys }),
|
|
57
|
+
}, AuthorizationInternalService.getRequestFetchOptions());
|
|
58
|
+
const responseBody = await response.json();
|
|
59
|
+
AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'deleteResourceAttributesSync');
|
|
60
|
+
return { attributes: responseBody['attributes'] };
|
|
118
61
|
}
|
|
119
62
|
/**
|
|
120
63
|
* Async function, this function only send the updates request to SNS and return before the change actually took place
|
|
@@ -124,8 +67,8 @@ class AuthorizationAttributesService {
|
|
|
124
67
|
* @param resourceAttributeOperations - Array of operations to do on resource attributes.
|
|
125
68
|
* @return {Promise<ResourceAttributesOperation[]>} Array of sent operations
|
|
126
69
|
* */
|
|
127
|
-
async updateResourceAttributesAsync(accountId, appName, callerActionIdentifier, resourceAttributeOperations) {
|
|
128
|
-
const topicArn = this.
|
|
70
|
+
static async updateResourceAttributesAsync(accountId, appName, callerActionIdentifier, resourceAttributeOperations) {
|
|
71
|
+
const topicArn = this.getSnsTopicArn();
|
|
129
72
|
const sendToSnsPromises = [];
|
|
130
73
|
const operationChucks = chunk(resourceAttributeOperations, ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE);
|
|
131
74
|
for (const operationsChunk of operationChucks) {
|
|
@@ -133,7 +76,7 @@ class AuthorizationAttributesService {
|
|
|
133
76
|
}
|
|
134
77
|
return (await Promise.all(sendToSnsPromises)).flat();
|
|
135
78
|
}
|
|
136
|
-
async sendSingleSnsMessage(topicArn, accountId, appName, callerActionIdentifier, operations) {
|
|
79
|
+
static async sendSingleSnsMessage(topicArn, accountId, appName, callerActionIdentifier, operations) {
|
|
137
80
|
const payload = {
|
|
138
81
|
kind: RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND,
|
|
139
82
|
payload: {
|
|
@@ -148,7 +91,7 @@ class AuthorizationAttributesService {
|
|
|
148
91
|
return operations;
|
|
149
92
|
}
|
|
150
93
|
catch (error) {
|
|
151
|
-
logger.error({ error, tag:
|
|
94
|
+
logger.error({ error, tag: this.LOG_TAG }, 'Authorization resource attributes async update: failed to send operations to SNS');
|
|
152
95
|
return [];
|
|
153
96
|
}
|
|
154
97
|
}
|
|
@@ -164,6 +107,9 @@ class AuthorizationAttributesService {
|
|
|
164
107
|
}
|
|
165
108
|
throw new Error('Unable to get sns topic arn from env variable');
|
|
166
109
|
}
|
|
110
|
+
static getResourceAttributesUrl(accountId) {
|
|
111
|
+
return `${process.env.AUTHORIZATION_URL}/attributes/${accountId}/resource`;
|
|
112
|
+
}
|
|
167
113
|
/**
|
|
168
114
|
* Checks we can contact the required SNS topic that used to send attribute updates to Authorization MS.
|
|
169
115
|
* This function can be used as health check for services that updating resource attributes in async is crucial.
|
|
@@ -172,18 +118,18 @@ class AuthorizationAttributesService {
|
|
|
172
118
|
* However, this is the best we can do without actually push dummy messages to the SNS.
|
|
173
119
|
* @return {Promise<boolean>} - true if succeeded
|
|
174
120
|
*/
|
|
175
|
-
async asyncResourceAttributesHealthCheck() {
|
|
121
|
+
static async asyncResourceAttributesHealthCheck() {
|
|
176
122
|
try {
|
|
177
|
-
const requestedTopicArn = this.
|
|
123
|
+
const requestedTopicArn = this.getSnsTopicArn();
|
|
178
124
|
const attributes = await getTopicAttributes(requestedTopicArn);
|
|
179
125
|
const isHealthy = !(!attributes || !('TopicArn' in attributes) || attributes.TopicArn !== requestedTopicArn);
|
|
180
126
|
if (!isHealthy) {
|
|
181
|
-
logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag:
|
|
127
|
+
logger.error({ requestedTopicArn, snsReturnedAttributes: attributes, tag: this.LOG_TAG }, 'authorization-attributes-service failed in health check');
|
|
182
128
|
}
|
|
183
129
|
return isHealthy;
|
|
184
130
|
}
|
|
185
131
|
catch (error) {
|
|
186
|
-
logger.error({ error, tag:
|
|
132
|
+
logger.error({ error, tag: this.LOG_TAG }, 'authorization-attributes-service got error during health check');
|
|
187
133
|
return false;
|
|
188
134
|
}
|
|
189
135
|
}
|
package/package.json
CHANGED
package/dist/constants.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare const APP_NAME = "authorization";
|
|
2
|
-
export declare const ERROR_MESSAGES: {
|
|
3
|
-
readonly HTTP_CLIENT_NOT_INITIALIZED: "MondayAuthorization: HTTP client is not initialized";
|
|
4
|
-
readonly REQUEST_FAILED: (method: string, status: number, reason: string) => string;
|
|
5
|
-
};
|
|
6
|
-
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC"}
|
package/dist/constants.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
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
|
-
|
|
9
|
-
exports.APP_NAME = APP_NAME;
|
|
10
|
-
exports.ERROR_MESSAGES = ERROR_MESSAGES;
|
package/dist/esm/constants.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare const APP_NAME = "authorization";
|
|
2
|
-
export declare const ERROR_MESSAGES: {
|
|
3
|
-
readonly HTTP_CLIENT_NOT_INITIALIZED: "MondayAuthorization: HTTP client is not initialized";
|
|
4
|
-
readonly REQUEST_FAILED: (method: string, status: number, reason: string) => string;
|
|
5
|
-
};
|
|
6
|
-
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC"}
|
package/dist/esm/constants.mjs
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
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
|
-
|
|
7
|
-
export { APP_NAME, ERROR_MESSAGES };
|