@mondaydotcomorg/monday-authorization 3.2.1 → 3.2.3-feature-bashanye-navigate-can-action-in-scope-to-graph-af77c6b
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/CHANGELOG.md +46 -0
- package/dist/authorization-attributes-service.d.ts.map +1 -1
- package/dist/authorization-attributes-service.js +4 -6
- package/dist/authorization-service.d.ts +8 -0
- package/dist/authorization-service.d.ts.map +1 -1
- package/dist/authorization-service.js +113 -19
- package/dist/constants/sns.d.ts +2 -1
- package/dist/constants/sns.d.ts.map +1 -1
- package/dist/constants/sns.js +4 -2
- package/dist/esm/authorization-attributes-service.d.ts.map +1 -1
- package/dist/esm/authorization-attributes-service.mjs +5 -7
- package/dist/esm/authorization-service.d.ts +8 -0
- package/dist/esm/authorization-service.d.ts.map +1 -1
- package/dist/esm/authorization-service.mjs +113 -19
- package/dist/esm/constants/sns.d.ts +2 -1
- package/dist/esm/constants/sns.d.ts.map +1 -1
- package/dist/esm/constants/sns.mjs +3 -2
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [2.0.0] - 2025-04-07
|
|
9
|
+
|
|
10
|
+
### ⚠ MAJOR CHANGE - PLEASE READ
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Calls to the monolith will be spread across the different profiles - `api-internal`, `slow` and `internal` (originally, all the calls to the platform went directly to `monday-app`)
|
|
15
|
+
|
|
16
|
+
## [1.2.9] - 2024-10-06
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- [`authz/bashanye/add-async-resource-attributes-support`](https://github.com/DaPulse/monday-npm-packages/pull/6859)
|
|
21
|
+
- `AuthorizationAttributesService` - now supports async upsert and delete - requests sent through SNS-SQS).
|
|
22
|
+
|
|
23
|
+
## [1.2.3] - 2024-06-10
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- [`feature/yarden/resource-attributes-api-support-authz-sdk (#5826)`](https://github.com/DaPulse/monday-npm-packages/pull/5826)
|
|
28
|
+
- `AuthorizationAttributesService` - now supports upsert (`upsertResourceAttributesSync`) and delete (`deleteResourceAttributesSync`) resource attributes in the authorization MS
|
|
29
|
+
|
|
30
|
+
## [1.2.0] - 2024-01-05
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- `isAuthorized` now return the unauthorized objects - regardless to the unauthorized ids (which may be missing resource ids if resource has no id, like `feature` e.g.)
|
|
35
|
+
|
|
36
|
+
## [1.1.0] - 2023-08-09
|
|
37
|
+
|
|
38
|
+
### ⚠ BREAKING CHANGES
|
|
39
|
+
|
|
40
|
+
- `canActionInScope` now returns an object of type `{ can: boolean; reason: string; }` instead of `boolean`.
|
|
41
|
+
This version is considered minor because no one uses this function yet.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- [`feature/idan/can-action-in-scope/change-behavior-on-error (#3689)`](https://github.com/DaPulse/monday-npm-packages/pull/3689)
|
|
46
|
+
- `canActionInScope`, `canActionInScopeMultiple` and `isAuthorized` are now throwing an error instead of returning `false` when an error occurs as part of the authorization http request (status code is not 2XX)
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAY3C,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;IAW7B;;;;;;;OAOG;IACG,kCAAkC,IAAI,OAAO,CAAC,OAAO,CAAC;CAoB7D"}
|
|
@@ -149,15 +149,13 @@ class AuthorizationAttributesService {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
static getSnsTopicArn() {
|
|
152
|
-
const
|
|
153
|
-
if (arnFromApi) {
|
|
154
|
-
return arnFromApi;
|
|
155
|
-
}
|
|
156
|
-
const jsonArnFromEnv = process.env[constants_sns.RESOURCE_ATTRIBUTES_SNS_ARN_SECRET_NAME];
|
|
157
|
-
const arnFromEnv = JSON.parse(jsonArnFromEnv).arn;
|
|
152
|
+
const arnFromEnv = process.env[constants_sns.SNS_ARN_ENV_VAR_NAME];
|
|
158
153
|
if (arnFromEnv) {
|
|
159
154
|
return arnFromEnv;
|
|
160
155
|
}
|
|
156
|
+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
157
|
+
return constants_sns.SNS_DEV_TEST_NAME;
|
|
158
|
+
}
|
|
161
159
|
throw new Error('Unable to get sns topic arn from env variable');
|
|
162
160
|
}
|
|
163
161
|
/**
|
|
@@ -30,6 +30,14 @@ export declare class AuthorizationService {
|
|
|
30
30
|
static canActionInScope(accountId: number, userId: number, action: string, scope: ScopeOptions): Promise<ScopedActionPermit>;
|
|
31
31
|
private static getProfile;
|
|
32
32
|
static canActionInScopeMultiple(accountId: number, userId: number, scopedActions: ScopedAction[]): Promise<ScopedActionResponseObject[]>;
|
|
33
|
+
private static buildScopedActionsPayload;
|
|
34
|
+
private static scopeToResource;
|
|
35
|
+
private static buildGraphRequestBody;
|
|
36
|
+
private static fetchGraphIsAllowed;
|
|
37
|
+
private static mapGraphResponse;
|
|
38
|
+
private static fetchPlatformCanActions;
|
|
39
|
+
private static toCamelCase;
|
|
40
|
+
private static mapPlatformResponse;
|
|
33
41
|
private static isAuthorizedSingular;
|
|
34
42
|
private static isAuthorizedMultiple;
|
|
35
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAc1C,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC7C;AAED,wBAAgB,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB,QAElF;AA6BD,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IACvD,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC;;;OAGG;WACU,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,QAAQ,EAAE,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC;WAEhB,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,2BAA2B,EAAE,mBAAmB,EAAE,GACjD,OAAO,CAAC,iBAAiB,CAAC;IAY7B;;;OAGG;WACU,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,OAAO,CAAC,OAAO,CAAC;mBAkBE,6BAA6B;IAclD,OAAO,CAAC,MAAM,CAAC,gBAAgB;WAIlB,gBAAgB,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,kBAAkB,CAAC;IAM9B,OAAO,CAAC,MAAM,CAAC,UAAU;WAsBZ,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAsBxC,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAMxC,OAAO,CAAC,MAAM,CAAC,eAAe;IAmB9B,OAAO,CAAC,MAAM,CAAC,qBAAqB;mBAyBf,mBAAmB;IAoCxC,OAAO,CAAC,MAAM,CAAC,gBAAgB;mBAoBV,uBAAuB;IAsC5C,OAAO,CAAC,MAAM,CAAC,WAAW;IAI1B,OAAO,CAAC,MAAM,CAAC,mBAAmB;mBAiBb,oBAAoB;mBAUpB,oBAAoB;CAmF1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F;AAED,wBAAsB,eAAe,kBAMpC;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAepG"}
|
|
@@ -23,6 +23,8 @@ const PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH = '/internal_ms/authorization/can_acti
|
|
|
23
23
|
const ALLOWED_SDK_PLATFORM_PROFILES_KEY = 'allowed-sdk-platform-profiles';
|
|
24
24
|
const IN_RELEASE_SDK_PLATFORM_PROFILES_KEY = 'in-release-sdk-platform-profile';
|
|
25
25
|
const PLATFORM_PROFILE_RELEASE_FF = 'sdk-platform-profiles';
|
|
26
|
+
const NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF = 'navigate-can-action-in-scope-to-graph';
|
|
27
|
+
const GRAPH_IS_ALLOWED_PATH = '/permissions/is-allowed';
|
|
26
28
|
function setRequestFetchOptions(customMondayFetchOptions) {
|
|
27
29
|
authorizationInternalService.AuthorizationInternalService.setRequestFetchOptions(customMondayFetchOptions);
|
|
28
30
|
}
|
|
@@ -95,16 +97,111 @@ class AuthorizationService {
|
|
|
95
97
|
return attributionsService.PlatformProfile.INTERNAL;
|
|
96
98
|
}
|
|
97
99
|
static async canActionInScopeMultiple(accountId, userId, scopedActions) {
|
|
98
|
-
const
|
|
100
|
+
const shouldNavigateToGraph = Boolean(this.igniteClient?.isReleased(NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF, { accountId, userId }));
|
|
99
101
|
const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
if (shouldNavigateToGraph) {
|
|
103
|
+
const response = await this.fetchGraphIsAllowed(internalAuthToken, scopedActions);
|
|
104
|
+
return this.mapGraphResponse(scopedActions, userId, response);
|
|
105
|
+
}
|
|
106
|
+
const profile = this.getProfile(accountId, userId);
|
|
107
|
+
const scopedActionsPayload = this.buildScopedActionsPayload(scopedActions);
|
|
108
|
+
const platformResponse = await this.fetchPlatformCanActions(profile, internalAuthToken, userId, scopedActionsPayload);
|
|
109
|
+
return this.mapPlatformResponse(platformResponse);
|
|
110
|
+
}
|
|
111
|
+
static buildScopedActionsPayload(scopedActions) {
|
|
112
|
+
return scopedActions.map(scopedAction => {
|
|
113
|
+
return { ...scopedAction, scope: mapKeys__default.default(scopedAction.scope, (_, key) => snakeCase__default.default(key)) };
|
|
102
114
|
});
|
|
115
|
+
}
|
|
116
|
+
static scopeToResource(scope) {
|
|
117
|
+
if ('workspaceId' in scope) {
|
|
118
|
+
return { resourceType: 'workspace', resourceId: scope.workspaceId };
|
|
119
|
+
}
|
|
120
|
+
if ('boardId' in scope) {
|
|
121
|
+
return { resourceType: 'board', resourceId: scope.boardId };
|
|
122
|
+
}
|
|
123
|
+
if ('pulseId' in scope) {
|
|
124
|
+
return { resourceType: 'pulse', resourceId: scope.pulseId };
|
|
125
|
+
}
|
|
126
|
+
if ('accountProductId' in scope) {
|
|
127
|
+
return { resourceType: 'account_product', resourceId: scope.accountProductId };
|
|
128
|
+
}
|
|
129
|
+
if ('accountId' in scope) {
|
|
130
|
+
return { resourceType: 'account', resourceId: scope.accountId };
|
|
131
|
+
}
|
|
132
|
+
throw new Error('Unsupported scope provided');
|
|
133
|
+
}
|
|
134
|
+
static buildGraphRequestBody(scopedActions) {
|
|
135
|
+
const resourcesAccumulator = {};
|
|
136
|
+
for (const { action, scope } of scopedActions) {
|
|
137
|
+
const { resourceType, resourceId } = this.scopeToResource(scope);
|
|
138
|
+
if (!resourcesAccumulator[resourceType]) {
|
|
139
|
+
resourcesAccumulator[resourceType] = {};
|
|
140
|
+
}
|
|
141
|
+
if (!resourcesAccumulator[resourceType][resourceId]) {
|
|
142
|
+
resourcesAccumulator[resourceType][resourceId] = new Set();
|
|
143
|
+
}
|
|
144
|
+
resourcesAccumulator[resourceType][resourceId].add(action);
|
|
145
|
+
}
|
|
146
|
+
const resourcesPayload = {};
|
|
147
|
+
for (const [resourceType, idMap] of Object.entries(resourcesAccumulator)) {
|
|
148
|
+
resourcesPayload[resourceType] = {};
|
|
149
|
+
for (const [idStr, actionsSet] of Object.entries(idMap)) {
|
|
150
|
+
const idNum = Number(idStr);
|
|
151
|
+
resourcesPayload[resourceType][idNum] = Array.from(actionsSet);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return resourcesPayload;
|
|
155
|
+
}
|
|
156
|
+
static async fetchGraphIsAllowed(internalAuthToken, scopedActions) {
|
|
157
|
+
const httpClient = tridentBackendApi.Api.getPart('httpClient');
|
|
158
|
+
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
159
|
+
const bodyPayload = this.buildGraphRequestBody(scopedActions);
|
|
160
|
+
try {
|
|
161
|
+
const response = await httpClient.fetch({
|
|
162
|
+
url: {
|
|
163
|
+
appName: 'authorization-graph',
|
|
164
|
+
path: GRAPH_IS_ALLOWED_PATH,
|
|
165
|
+
},
|
|
166
|
+
method: 'POST',
|
|
167
|
+
headers: {
|
|
168
|
+
Authorization: internalAuthToken,
|
|
169
|
+
'Content-Type': 'application/json',
|
|
170
|
+
...attributionHeaders,
|
|
171
|
+
},
|
|
172
|
+
body: JSON.stringify(bodyPayload),
|
|
173
|
+
}, {
|
|
174
|
+
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
175
|
+
retryPolicy: authorizationInternalService.AuthorizationInternalService.getRetriesPolicy(),
|
|
176
|
+
});
|
|
177
|
+
return response;
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
181
|
+
authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
|
|
182
|
+
}
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
static mapGraphResponse(scopedActions, userId, graphResponse) {
|
|
187
|
+
const resources = graphResponse ?? {};
|
|
188
|
+
return scopedActions.map(scopedAction => {
|
|
189
|
+
const { action, scope } = scopedAction;
|
|
190
|
+
const { resourceType, resourceId } = this.scopeToResource(scope);
|
|
191
|
+
const permissionResult = resources?.[resourceType]?.[String(resourceId)]?.[action];
|
|
192
|
+
const permit = {
|
|
193
|
+
can: permissionResult?.can ?? false,
|
|
194
|
+
reason: { key: permissionResult?.reason ?? 'unknown' },
|
|
195
|
+
technicalReason: 0,
|
|
196
|
+
};
|
|
197
|
+
return { scopedAction, permit };
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
static async fetchPlatformCanActions(profile, internalAuthToken, userId, scopedActionsPayload) {
|
|
103
201
|
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
104
202
|
const httpClient = tridentBackendApi.Api.getPart('httpClient');
|
|
105
|
-
let response;
|
|
106
203
|
try {
|
|
107
|
-
response = await httpClient.fetch({
|
|
204
|
+
const response = await httpClient.fetch({
|
|
108
205
|
url: {
|
|
109
206
|
appName: 'platform',
|
|
110
207
|
path: PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH,
|
|
@@ -116,40 +213,37 @@ class AuthorizationService {
|
|
|
116
213
|
'Content-Type': 'application/json',
|
|
117
214
|
...attributionHeaders,
|
|
118
215
|
},
|
|
119
|
-
body: JSON.stringify({
|
|
120
|
-
user_id: userId,
|
|
121
|
-
scoped_actions: scopedActionsPayload,
|
|
122
|
-
}),
|
|
216
|
+
body: JSON.stringify({ user_id: userId, scoped_actions: scopedActionsPayload }),
|
|
123
217
|
}, {
|
|
124
218
|
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
125
219
|
retryPolicy: authorizationInternalService.AuthorizationInternalService.getRetriesPolicy(),
|
|
126
220
|
});
|
|
221
|
+
return response;
|
|
127
222
|
}
|
|
128
223
|
catch (err) {
|
|
129
224
|
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
130
225
|
authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
|
|
131
226
|
}
|
|
132
|
-
|
|
133
|
-
throw err;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
function toCamelCase(obj) {
|
|
137
|
-
return mapKeys__default.default(obj, (_, key) => camelCase__default.default(key));
|
|
227
|
+
throw err;
|
|
138
228
|
}
|
|
229
|
+
}
|
|
230
|
+
static toCamelCase(obj) {
|
|
231
|
+
return mapKeys__default.default(obj, (_, key) => camelCase__default.default(key));
|
|
232
|
+
}
|
|
233
|
+
static mapPlatformResponse(response) {
|
|
139
234
|
if (!response) {
|
|
140
235
|
authorizationInternalService.logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
|
|
141
236
|
throw new Error('AuthorizationService: missing response');
|
|
142
237
|
}
|
|
143
|
-
|
|
238
|
+
return response.result.map(responseObject => {
|
|
144
239
|
const { scopedAction, permit } = responseObject;
|
|
145
240
|
const { scope } = scopedAction;
|
|
146
241
|
return {
|
|
147
242
|
...responseObject,
|
|
148
|
-
scopedAction: { ...scopedAction, scope: toCamelCase(scope) },
|
|
149
|
-
permit: toCamelCase(permit),
|
|
243
|
+
scopedAction: { ...scopedAction, scope: this.toCamelCase(scope) },
|
|
244
|
+
permit: this.toCamelCase(permit),
|
|
150
245
|
};
|
|
151
246
|
});
|
|
152
|
-
return scopedActionsResponseObjects;
|
|
153
247
|
}
|
|
154
248
|
static async isAuthorizedSingular(accountId, userId, resources, action) {
|
|
155
249
|
const { authorizationObjects } = createAuthorizationParams(resources, action);
|
package/dist/constants/sns.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const SNS_ARN_ENV_VAR_NAME = "SHARED_AUTHORIZATION_SNS_ENDPOINT_RESOURCE_ATTRIBUTES";
|
|
2
|
+
export declare const SNS_DEV_TEST_NAME = "arn:aws:sns:us-east-1:000000000000:monday-authorization-resource-attributes-sns-local";
|
|
2
3
|
export declare const RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND = "resourceAttributeModification";
|
|
3
4
|
export declare const ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE = 100;
|
|
4
5
|
//# sourceMappingURL=sns.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sns.d.ts","sourceRoot":"","sources":["../../src/constants/sns.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"sns.d.ts","sourceRoot":"","sources":["../../src/constants/sns.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,0DAA0D,CAAC;AAC5F,eAAO,MAAM,iBAAiB,0FAC2D,CAAC;AAC1F,eAAO,MAAM,qDAAqD,kCAAkC,CAAC;AACrG,eAAO,MAAM,oDAAoD,MAAM,CAAC"}
|
package/dist/constants/sns.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const SNS_ARN_ENV_VAR_NAME = 'SHARED_AUTHORIZATION_SNS_ENDPOINT_RESOURCE_ATTRIBUTES';
|
|
4
|
+
const SNS_DEV_TEST_NAME = 'arn:aws:sns:us-east-1:000000000000:monday-authorization-resource-attributes-sns-local';
|
|
4
5
|
const RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND = 'resourceAttributeModification';
|
|
5
6
|
const ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE = 100;
|
|
6
7
|
|
|
7
8
|
exports.ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE = ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE;
|
|
8
|
-
exports.RESOURCE_ATTRIBUTES_SNS_ARN_SECRET_NAME = RESOURCE_ATTRIBUTES_SNS_ARN_SECRET_NAME;
|
|
9
9
|
exports.RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND = RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND;
|
|
10
|
+
exports.SNS_ARN_ENV_VAR_NAME = SNS_ARN_ENV_VAR_NAME;
|
|
11
|
+
exports.SNS_DEV_TEST_NAME = SNS_DEV_TEST_NAME;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAY3C,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;IAW7B;;;;;;;OAOG;IACG,kCAAkC,IAAI,OAAO,CAAC,OAAO,CAAC;CAoB7D"}
|
|
@@ -4,7 +4,7 @@ import { sendToSns, getTopicAttributes } from '@mondaydotcomorg/monday-sns';
|
|
|
4
4
|
import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
|
|
5
5
|
import { logger } from './authorization-internal-service.mjs';
|
|
6
6
|
import { getAttributionsFromApi } from './attributions-service.mjs';
|
|
7
|
-
import { ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE,
|
|
7
|
+
import { ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE, SNS_ARN_ENV_VAR_NAME, SNS_DEV_TEST_NAME, RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND } from './constants/sns.mjs';
|
|
8
8
|
import { ERROR_MESSAGES, DEFAULT_FETCH_OPTIONS, APP_NAME } from './constants.mjs';
|
|
9
9
|
|
|
10
10
|
class AuthorizationAttributesService {
|
|
@@ -143,15 +143,13 @@ class AuthorizationAttributesService {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
static getSnsTopicArn() {
|
|
146
|
-
const
|
|
147
|
-
if (arnFromApi) {
|
|
148
|
-
return arnFromApi;
|
|
149
|
-
}
|
|
150
|
-
const jsonArnFromEnv = process.env[RESOURCE_ATTRIBUTES_SNS_ARN_SECRET_NAME];
|
|
151
|
-
const arnFromEnv = JSON.parse(jsonArnFromEnv).arn;
|
|
146
|
+
const arnFromEnv = process.env[SNS_ARN_ENV_VAR_NAME];
|
|
152
147
|
if (arnFromEnv) {
|
|
153
148
|
return arnFromEnv;
|
|
154
149
|
}
|
|
150
|
+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
151
|
+
return SNS_DEV_TEST_NAME;
|
|
152
|
+
}
|
|
155
153
|
throw new Error('Unable to get sns topic arn from env variable');
|
|
156
154
|
}
|
|
157
155
|
/**
|
|
@@ -30,6 +30,14 @@ export declare class AuthorizationService {
|
|
|
30
30
|
static canActionInScope(accountId: number, userId: number, action: string, scope: ScopeOptions): Promise<ScopedActionPermit>;
|
|
31
31
|
private static getProfile;
|
|
32
32
|
static canActionInScopeMultiple(accountId: number, userId: number, scopedActions: ScopedAction[]): Promise<ScopedActionResponseObject[]>;
|
|
33
|
+
private static buildScopedActionsPayload;
|
|
34
|
+
private static scopeToResource;
|
|
35
|
+
private static buildGraphRequestBody;
|
|
36
|
+
private static fetchGraphIsAllowed;
|
|
37
|
+
private static mapGraphResponse;
|
|
38
|
+
private static fetchPlatformCanActions;
|
|
39
|
+
private static toCamelCase;
|
|
40
|
+
private static mapPlatformResponse;
|
|
33
41
|
private static isAuthorizedSingular;
|
|
34
42
|
private static isAuthorizedMultiple;
|
|
35
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAc1C,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC7C;AAED,wBAAgB,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB,QAElF;AA6BD,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IACvD,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC;;;OAGG;WACU,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,QAAQ,EAAE,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC;WAEhB,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,2BAA2B,EAAE,mBAAmB,EAAE,GACjD,OAAO,CAAC,iBAAiB,CAAC;IAY7B;;;OAGG;WACU,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,OAAO,CAAC,OAAO,CAAC;mBAkBE,6BAA6B;IAclD,OAAO,CAAC,MAAM,CAAC,gBAAgB;WAIlB,gBAAgB,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,kBAAkB,CAAC;IAM9B,OAAO,CAAC,MAAM,CAAC,UAAU;WAsBZ,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAsBxC,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAMxC,OAAO,CAAC,MAAM,CAAC,eAAe;IAmB9B,OAAO,CAAC,MAAM,CAAC,qBAAqB;mBAyBf,mBAAmB;IAoCxC,OAAO,CAAC,MAAM,CAAC,gBAAgB;mBAoBV,uBAAuB;IAsC5C,OAAO,CAAC,MAAM,CAAC,WAAW;IAI1B,OAAO,CAAC,MAAM,CAAC,mBAAmB;mBAiBb,oBAAoB;mBAUpB,oBAAoB;CAmF1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F;AAED,wBAAsB,eAAe,kBAMpC;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAepG"}
|
|
@@ -15,6 +15,8 @@ const PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH = '/internal_ms/authorization/can_acti
|
|
|
15
15
|
const ALLOWED_SDK_PLATFORM_PROFILES_KEY = 'allowed-sdk-platform-profiles';
|
|
16
16
|
const IN_RELEASE_SDK_PLATFORM_PROFILES_KEY = 'in-release-sdk-platform-profile';
|
|
17
17
|
const PLATFORM_PROFILE_RELEASE_FF = 'sdk-platform-profiles';
|
|
18
|
+
const NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF = 'navigate-can-action-in-scope-to-graph';
|
|
19
|
+
const GRAPH_IS_ALLOWED_PATH = '/permissions/is-allowed';
|
|
18
20
|
function setRequestFetchOptions(customMondayFetchOptions) {
|
|
19
21
|
AuthorizationInternalService.setRequestFetchOptions(customMondayFetchOptions);
|
|
20
22
|
}
|
|
@@ -87,16 +89,111 @@ class AuthorizationService {
|
|
|
87
89
|
return PlatformProfile.INTERNAL;
|
|
88
90
|
}
|
|
89
91
|
static async canActionInScopeMultiple(accountId, userId, scopedActions) {
|
|
90
|
-
const
|
|
92
|
+
const shouldNavigateToGraph = Boolean(this.igniteClient?.isReleased(NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF, { accountId, userId }));
|
|
91
93
|
const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
if (shouldNavigateToGraph) {
|
|
95
|
+
const response = await this.fetchGraphIsAllowed(internalAuthToken, scopedActions);
|
|
96
|
+
return this.mapGraphResponse(scopedActions, userId, response);
|
|
97
|
+
}
|
|
98
|
+
const profile = this.getProfile(accountId, userId);
|
|
99
|
+
const scopedActionsPayload = this.buildScopedActionsPayload(scopedActions);
|
|
100
|
+
const platformResponse = await this.fetchPlatformCanActions(profile, internalAuthToken, userId, scopedActionsPayload);
|
|
101
|
+
return this.mapPlatformResponse(platformResponse);
|
|
102
|
+
}
|
|
103
|
+
static buildScopedActionsPayload(scopedActions) {
|
|
104
|
+
return scopedActions.map(scopedAction => {
|
|
105
|
+
return { ...scopedAction, scope: mapKeys(scopedAction.scope, (_, key) => snakeCase(key)) };
|
|
94
106
|
});
|
|
107
|
+
}
|
|
108
|
+
static scopeToResource(scope) {
|
|
109
|
+
if ('workspaceId' in scope) {
|
|
110
|
+
return { resourceType: 'workspace', resourceId: scope.workspaceId };
|
|
111
|
+
}
|
|
112
|
+
if ('boardId' in scope) {
|
|
113
|
+
return { resourceType: 'board', resourceId: scope.boardId };
|
|
114
|
+
}
|
|
115
|
+
if ('pulseId' in scope) {
|
|
116
|
+
return { resourceType: 'pulse', resourceId: scope.pulseId };
|
|
117
|
+
}
|
|
118
|
+
if ('accountProductId' in scope) {
|
|
119
|
+
return { resourceType: 'account_product', resourceId: scope.accountProductId };
|
|
120
|
+
}
|
|
121
|
+
if ('accountId' in scope) {
|
|
122
|
+
return { resourceType: 'account', resourceId: scope.accountId };
|
|
123
|
+
}
|
|
124
|
+
throw new Error('Unsupported scope provided');
|
|
125
|
+
}
|
|
126
|
+
static buildGraphRequestBody(scopedActions) {
|
|
127
|
+
const resourcesAccumulator = {};
|
|
128
|
+
for (const { action, scope } of scopedActions) {
|
|
129
|
+
const { resourceType, resourceId } = this.scopeToResource(scope);
|
|
130
|
+
if (!resourcesAccumulator[resourceType]) {
|
|
131
|
+
resourcesAccumulator[resourceType] = {};
|
|
132
|
+
}
|
|
133
|
+
if (!resourcesAccumulator[resourceType][resourceId]) {
|
|
134
|
+
resourcesAccumulator[resourceType][resourceId] = new Set();
|
|
135
|
+
}
|
|
136
|
+
resourcesAccumulator[resourceType][resourceId].add(action);
|
|
137
|
+
}
|
|
138
|
+
const resourcesPayload = {};
|
|
139
|
+
for (const [resourceType, idMap] of Object.entries(resourcesAccumulator)) {
|
|
140
|
+
resourcesPayload[resourceType] = {};
|
|
141
|
+
for (const [idStr, actionsSet] of Object.entries(idMap)) {
|
|
142
|
+
const idNum = Number(idStr);
|
|
143
|
+
resourcesPayload[resourceType][idNum] = Array.from(actionsSet);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return resourcesPayload;
|
|
147
|
+
}
|
|
148
|
+
static async fetchGraphIsAllowed(internalAuthToken, scopedActions) {
|
|
149
|
+
const httpClient = Api.getPart('httpClient');
|
|
150
|
+
const attributionHeaders = getAttributionsFromApi();
|
|
151
|
+
const bodyPayload = this.buildGraphRequestBody(scopedActions);
|
|
152
|
+
try {
|
|
153
|
+
const response = await httpClient.fetch({
|
|
154
|
+
url: {
|
|
155
|
+
appName: 'authorization-graph',
|
|
156
|
+
path: GRAPH_IS_ALLOWED_PATH,
|
|
157
|
+
},
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: {
|
|
160
|
+
Authorization: internalAuthToken,
|
|
161
|
+
'Content-Type': 'application/json',
|
|
162
|
+
...attributionHeaders,
|
|
163
|
+
},
|
|
164
|
+
body: JSON.stringify(bodyPayload),
|
|
165
|
+
}, {
|
|
166
|
+
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
167
|
+
retryPolicy: AuthorizationInternalService.getRetriesPolicy(),
|
|
168
|
+
});
|
|
169
|
+
return response;
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
if (err instanceof HttpFetcherError) {
|
|
173
|
+
AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
|
|
174
|
+
}
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
static mapGraphResponse(scopedActions, userId, graphResponse) {
|
|
179
|
+
const resources = graphResponse ?? {};
|
|
180
|
+
return scopedActions.map(scopedAction => {
|
|
181
|
+
const { action, scope } = scopedAction;
|
|
182
|
+
const { resourceType, resourceId } = this.scopeToResource(scope);
|
|
183
|
+
const permissionResult = resources?.[resourceType]?.[String(resourceId)]?.[action];
|
|
184
|
+
const permit = {
|
|
185
|
+
can: permissionResult?.can ?? false,
|
|
186
|
+
reason: { key: permissionResult?.reason ?? 'unknown' },
|
|
187
|
+
technicalReason: 0,
|
|
188
|
+
};
|
|
189
|
+
return { scopedAction, permit };
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
static async fetchPlatformCanActions(profile, internalAuthToken, userId, scopedActionsPayload) {
|
|
95
193
|
const attributionHeaders = getAttributionsFromApi();
|
|
96
194
|
const httpClient = Api.getPart('httpClient');
|
|
97
|
-
let response;
|
|
98
195
|
try {
|
|
99
|
-
response = await httpClient.fetch({
|
|
196
|
+
const response = await httpClient.fetch({
|
|
100
197
|
url: {
|
|
101
198
|
appName: 'platform',
|
|
102
199
|
path: PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH,
|
|
@@ -108,40 +205,37 @@ class AuthorizationService {
|
|
|
108
205
|
'Content-Type': 'application/json',
|
|
109
206
|
...attributionHeaders,
|
|
110
207
|
},
|
|
111
|
-
body: JSON.stringify({
|
|
112
|
-
user_id: userId,
|
|
113
|
-
scoped_actions: scopedActionsPayload,
|
|
114
|
-
}),
|
|
208
|
+
body: JSON.stringify({ user_id: userId, scoped_actions: scopedActionsPayload }),
|
|
115
209
|
}, {
|
|
116
210
|
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
117
211
|
retryPolicy: AuthorizationInternalService.getRetriesPolicy(),
|
|
118
212
|
});
|
|
213
|
+
return response;
|
|
119
214
|
}
|
|
120
215
|
catch (err) {
|
|
121
216
|
if (err instanceof HttpFetcherError) {
|
|
122
217
|
AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
|
|
123
218
|
}
|
|
124
|
-
|
|
125
|
-
throw err;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function toCamelCase(obj) {
|
|
129
|
-
return mapKeys(obj, (_, key) => camelCase(key));
|
|
219
|
+
throw err;
|
|
130
220
|
}
|
|
221
|
+
}
|
|
222
|
+
static toCamelCase(obj) {
|
|
223
|
+
return mapKeys(obj, (_, key) => camelCase(key));
|
|
224
|
+
}
|
|
225
|
+
static mapPlatformResponse(response) {
|
|
131
226
|
if (!response) {
|
|
132
227
|
logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
|
|
133
228
|
throw new Error('AuthorizationService: missing response');
|
|
134
229
|
}
|
|
135
|
-
|
|
230
|
+
return response.result.map(responseObject => {
|
|
136
231
|
const { scopedAction, permit } = responseObject;
|
|
137
232
|
const { scope } = scopedAction;
|
|
138
233
|
return {
|
|
139
234
|
...responseObject,
|
|
140
|
-
scopedAction: { ...scopedAction, scope: toCamelCase(scope) },
|
|
141
|
-
permit: toCamelCase(permit),
|
|
235
|
+
scopedAction: { ...scopedAction, scope: this.toCamelCase(scope) },
|
|
236
|
+
permit: this.toCamelCase(permit),
|
|
142
237
|
};
|
|
143
238
|
});
|
|
144
|
-
return scopedActionsResponseObjects;
|
|
145
239
|
}
|
|
146
240
|
static async isAuthorizedSingular(accountId, userId, resources, action) {
|
|
147
241
|
const { authorizationObjects } = createAuthorizationParams(resources, action);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const SNS_ARN_ENV_VAR_NAME = "SHARED_AUTHORIZATION_SNS_ENDPOINT_RESOURCE_ATTRIBUTES";
|
|
2
|
+
export declare const SNS_DEV_TEST_NAME = "arn:aws:sns:us-east-1:000000000000:monday-authorization-resource-attributes-sns-local";
|
|
2
3
|
export declare const RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND = "resourceAttributeModification";
|
|
3
4
|
export declare const ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE = 100;
|
|
4
5
|
//# sourceMappingURL=sns.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sns.d.ts","sourceRoot":"","sources":["../../../src/constants/sns.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"sns.d.ts","sourceRoot":"","sources":["../../../src/constants/sns.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,0DAA0D,CAAC;AAC5F,eAAO,MAAM,iBAAiB,0FAC2D,CAAC;AAC1F,eAAO,MAAM,qDAAqD,kCAAkC,CAAC;AACrG,eAAO,MAAM,oDAAoD,MAAM,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const SNS_ARN_ENV_VAR_NAME = 'SHARED_AUTHORIZATION_SNS_ENDPOINT_RESOURCE_ATTRIBUTES';
|
|
2
|
+
const SNS_DEV_TEST_NAME = 'arn:aws:sns:us-east-1:000000000000:monday-authorization-resource-attributes-sns-local';
|
|
2
3
|
const RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND = 'resourceAttributeModification';
|
|
3
4
|
const ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE = 100;
|
|
4
5
|
|
|
5
|
-
export { ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE,
|
|
6
|
+
export { ASYNC_RESOURCE_ATTRIBUTES_MAX_OPERATIONS_PER_MESSAGE, RESOURCE_ATTRIBUTES_SNS_UPDATE_OPERATION_MESSAGE_KIND, SNS_ARN_ENV_VAR_NAME, SNS_DEV_TEST_NAME };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mondaydotcomorg/monday-authorization",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3-feature-bashanye-navigate-can-action-in-scope-to-graph-af77c6b",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"test": "trident-library test",
|
|
17
17
|
"lint": "trident-library lint",
|
|
18
|
+
"lint:fix": "trident-library lint --fix",
|
|
18
19
|
"build": "trident-library build",
|
|
19
20
|
"watch": "trident-library build -w"
|
|
20
21
|
},
|
|
@@ -61,4 +62,4 @@
|
|
|
61
62
|
"url": "https://github.com/DaPulse/authorization-domain.git",
|
|
62
63
|
"directory": "packages/monday-authorization"
|
|
63
64
|
}
|
|
64
|
-
}
|
|
65
|
+
}
|