@mondaydotcomorg/monday-authorization 3.2.3-feature-bashanye-navigate-can-action-in-scope-to-graph-af77c6b → 3.2.3

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.
@@ -30,14 +30,6 @@ 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;
41
33
  private static isAuthorizedSingular;
42
34
  private static isAuthorizedMultiple;
43
35
  }
@@ -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;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"}
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;AAY1C,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;AAeD,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;mBAkEnB,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,8 +23,6 @@ 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';
28
26
  function setRequestFetchOptions(customMondayFetchOptions) {
29
27
  authorizationInternalService.AuthorizationInternalService.setRequestFetchOptions(customMondayFetchOptions);
30
28
  }
@@ -97,111 +95,16 @@ class AuthorizationService {
97
95
  return attributionsService.PlatformProfile.INTERNAL;
98
96
  }
99
97
  static async canActionInScopeMultiple(accountId, userId, scopedActions) {
100
- const shouldNavigateToGraph = Boolean(this.igniteClient?.isReleased(NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF, { accountId, userId }));
101
- const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
102
- if (shouldNavigateToGraph) {
103
- const response = await this.fetchGraphIsAllowed(internalAuthToken, scopedActions);
104
- return this.mapGraphResponse(scopedActions, userId, response);
105
- }
106
98
  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)) };
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 };
99
+ const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
100
+ const scopedActionsPayload = scopedActions.map(scopedAction => {
101
+ return { ...scopedAction, scope: mapKeys__default.default(scopedAction.scope, (_, key) => snakeCase__default.default(key)) }; // for example: { workspaceId: 1 } => { workspace_id: 1 }
198
102
  });
199
- }
200
- static async fetchPlatformCanActions(profile, internalAuthToken, userId, scopedActionsPayload) {
201
103
  const attributionHeaders = attributionsService.getAttributionsFromApi();
202
104
  const httpClient = tridentBackendApi.Api.getPart('httpClient');
105
+ let response;
203
106
  try {
204
- const response = await httpClient.fetch({
107
+ response = await httpClient.fetch({
205
108
  url: {
206
109
  appName: 'platform',
207
110
  path: PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH,
@@ -213,37 +116,40 @@ class AuthorizationService {
213
116
  'Content-Type': 'application/json',
214
117
  ...attributionHeaders,
215
118
  },
216
- body: JSON.stringify({ user_id: userId, scoped_actions: scopedActionsPayload }),
119
+ body: JSON.stringify({
120
+ user_id: userId,
121
+ scoped_actions: scopedActionsPayload,
122
+ }),
217
123
  }, {
218
124
  timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
219
125
  retryPolicy: authorizationInternalService.AuthorizationInternalService.getRetriesPolicy(),
220
126
  });
221
- return response;
222
127
  }
223
128
  catch (err) {
224
129
  if (err instanceof mondayFetchApi.HttpFetcherError) {
225
130
  authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
226
131
  }
227
- throw err;
132
+ else {
133
+ throw err;
134
+ }
135
+ }
136
+ function toCamelCase(obj) {
137
+ return mapKeys__default.default(obj, (_, key) => camelCase__default.default(key));
228
138
  }
229
- }
230
- static toCamelCase(obj) {
231
- return mapKeys__default.default(obj, (_, key) => camelCase__default.default(key));
232
- }
233
- static mapPlatformResponse(response) {
234
139
  if (!response) {
235
140
  authorizationInternalService.logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
236
141
  throw new Error('AuthorizationService: missing response');
237
142
  }
238
- return response.result.map(responseObject => {
143
+ const scopedActionsResponseObjects = response.result.map(responseObject => {
239
144
  const { scopedAction, permit } = responseObject;
240
145
  const { scope } = scopedAction;
241
146
  return {
242
147
  ...responseObject,
243
- scopedAction: { ...scopedAction, scope: this.toCamelCase(scope) },
244
- permit: this.toCamelCase(permit),
148
+ scopedAction: { ...scopedAction, scope: toCamelCase(scope) },
149
+ permit: toCamelCase(permit),
245
150
  };
246
151
  });
152
+ return scopedActionsResponseObjects;
247
153
  }
248
154
  static async isAuthorizedSingular(accountId, userId, resources, action) {
249
155
  const { authorizationObjects } = createAuthorizationParams(resources, action);
@@ -30,14 +30,6 @@ 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;
41
33
  private static isAuthorizedSingular;
42
34
  private static isAuthorizedMultiple;
43
35
  }
@@ -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;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"}
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;AAY1C,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;AAeD,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;mBAkEnB,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,8 +15,6 @@ 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';
20
18
  function setRequestFetchOptions(customMondayFetchOptions) {
21
19
  AuthorizationInternalService.setRequestFetchOptions(customMondayFetchOptions);
22
20
  }
@@ -89,111 +87,16 @@ class AuthorizationService {
89
87
  return PlatformProfile.INTERNAL;
90
88
  }
91
89
  static async canActionInScopeMultiple(accountId, userId, scopedActions) {
92
- const shouldNavigateToGraph = Boolean(this.igniteClient?.isReleased(NAVIGATE_CAN_ACTION_IN_SCOPE_TO_GRAPH_FF, { accountId, userId }));
93
- const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
94
- if (shouldNavigateToGraph) {
95
- const response = await this.fetchGraphIsAllowed(internalAuthToken, scopedActions);
96
- return this.mapGraphResponse(scopedActions, userId, response);
97
- }
98
90
  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)) };
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 };
91
+ const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
92
+ const scopedActionsPayload = scopedActions.map(scopedAction => {
93
+ return { ...scopedAction, scope: mapKeys(scopedAction.scope, (_, key) => snakeCase(key)) }; // for example: { workspaceId: 1 } => { workspace_id: 1 }
190
94
  });
191
- }
192
- static async fetchPlatformCanActions(profile, internalAuthToken, userId, scopedActionsPayload) {
193
95
  const attributionHeaders = getAttributionsFromApi();
194
96
  const httpClient = Api.getPart('httpClient');
97
+ let response;
195
98
  try {
196
- const response = await httpClient.fetch({
99
+ response = await httpClient.fetch({
197
100
  url: {
198
101
  appName: 'platform',
199
102
  path: PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH,
@@ -205,37 +108,40 @@ class AuthorizationService {
205
108
  'Content-Type': 'application/json',
206
109
  ...attributionHeaders,
207
110
  },
208
- body: JSON.stringify({ user_id: userId, scoped_actions: scopedActionsPayload }),
111
+ body: JSON.stringify({
112
+ user_id: userId,
113
+ scoped_actions: scopedActionsPayload,
114
+ }),
209
115
  }, {
210
116
  timeout: AuthorizationInternalService.getRequestTimeout(),
211
117
  retryPolicy: AuthorizationInternalService.getRetriesPolicy(),
212
118
  });
213
- return response;
214
119
  }
215
120
  catch (err) {
216
121
  if (err instanceof HttpFetcherError) {
217
122
  AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
218
123
  }
219
- throw err;
124
+ else {
125
+ throw err;
126
+ }
127
+ }
128
+ function toCamelCase(obj) {
129
+ return mapKeys(obj, (_, key) => camelCase(key));
220
130
  }
221
- }
222
- static toCamelCase(obj) {
223
- return mapKeys(obj, (_, key) => camelCase(key));
224
- }
225
- static mapPlatformResponse(response) {
226
131
  if (!response) {
227
132
  logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
228
133
  throw new Error('AuthorizationService: missing response');
229
134
  }
230
- return response.result.map(responseObject => {
135
+ const scopedActionsResponseObjects = response.result.map(responseObject => {
231
136
  const { scopedAction, permit } = responseObject;
232
137
  const { scope } = scopedAction;
233
138
  return {
234
139
  ...responseObject,
235
- scopedAction: { ...scopedAction, scope: this.toCamelCase(scope) },
236
- permit: this.toCamelCase(permit),
140
+ scopedAction: { ...scopedAction, scope: toCamelCase(scope) },
141
+ permit: toCamelCase(permit),
237
142
  };
238
143
  });
144
+ return scopedActionsResponseObjects;
239
145
  }
240
146
  static async isAuthorizedSingular(accountId, userId, resources, action) {
241
147
  const { authorizationObjects } = createAuthorizationParams(resources, action);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mondaydotcomorg/monday-authorization",
3
- "version": "3.2.3-feature-bashanye-navigate-can-action-in-scope-to-graph-af77c6b",
3
+ "version": "3.2.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "BSD-3-Clause",
@@ -62,4 +62,4 @@
62
62
  "url": "https://github.com/DaPulse/authorization-domain.git",
63
63
  "directory": "packages/monday-authorization"
64
64
  }
65
- }
65
+ }
package/CHANGELOG.md DELETED
@@ -1,46 +0,0 @@
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)