@mondaydotcomorg/monday-authorization 3.3.0-feat-add-graph-api-routing-support-c17713e → 3.3.0-feat-add-graph-api-routing-support-5c7bcd4

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.
Files changed (32) hide show
  1. package/README.md +15 -10
  2. package/dist/authorization-internal-service.d.ts +1 -1
  3. package/dist/authorization-internal-service.d.ts.map +1 -1
  4. package/dist/authorization-service.d.ts.map +1 -1
  5. package/dist/authorization-service.js +1 -14
  6. package/dist/clients/graph-api.d.ts.map +1 -1
  7. package/dist/clients/graph-api.js +3 -9
  8. package/dist/clients/platform-api.d.ts.map +1 -1
  9. package/dist/clients/platform-api.js +3 -9
  10. package/dist/esm/authorization-internal-service.d.ts +1 -1
  11. package/dist/esm/authorization-internal-service.d.ts.map +1 -1
  12. package/dist/esm/authorization-service.d.ts.map +1 -1
  13. package/dist/esm/authorization-service.mjs +1 -14
  14. package/dist/esm/clients/graph-api.d.ts.map +1 -1
  15. package/dist/esm/clients/graph-api.mjs +3 -9
  16. package/dist/esm/clients/platform-api.d.ts.map +1 -1
  17. package/dist/esm/clients/platform-api.mjs +3 -9
  18. package/dist/esm/metrics-service.mjs +5 -5
  19. package/dist/esm/utils/api-error-handler.d.ts +2 -0
  20. package/dist/esm/utils/api-error-handler.d.ts.map +1 -0
  21. package/dist/esm/utils/api-error-handler.mjs +18 -0
  22. package/dist/metrics-service.js +5 -5
  23. package/dist/utils/api-error-handler.d.ts +2 -0
  24. package/dist/utils/api-error-handler.d.ts.map +1 -0
  25. package/dist/utils/api-error-handler.js +20 -0
  26. package/package.json +1 -1
  27. package/src/authorization-internal-service.ts +1 -1
  28. package/src/authorization-service.ts +1 -17
  29. package/src/clients/graph-api.ts +3 -9
  30. package/src/clients/platform-api.ts +3 -9
  31. package/src/metrics-service.ts +5 -5
  32. package/src/utils/api-error-handler.ts +21 -0
package/README.md CHANGED
@@ -41,6 +41,15 @@ startServer(...)
41
41
  - grantedFeatureRedisExpirationInSeconds - (optional), redis TTL for cached granted features, default set to 5 minutes
42
42
  - metrics - (optional), configure internal DataDog/observability integration. Defaults to `process.env.APP_NAME` as the service name, uses the standard StatsD endpoint (`localhost:8125`) when host/port are not provided, and disables emission automatically in test/development environments (override with `disabled`).
43
43
 
44
+ ### Metrics & Observability
45
+
46
+ - `prometheus` (optional) enables the legacy Prometheus summary `authorization_check_response_time` with labels `resourceType`, `action`, `isAuthorized`, and `responseStatus`.
47
+ - `metrics` (optional) enables StatsD emission through `@mondaydotcomorg/monday-observability-kit` with:
48
+ - `authorization.authorizationCheck.platform.duration` / `.graph.duration` (distributions per API path)
49
+ - `authorization.authorizationCheck.platform.error` / `.graph.error` counters (with `statusCode` tag)
50
+ - When `metrics.disabled` is omitted, the SDK automatically disables StatsD in `test`/`development` environments.
51
+ - StatsD requires `DOGSTATSD_HOST` / `DOGSTATSD_PORT` (or the defaults `localhost:8125`). Errors are logged and skipped if the client is unavailable.
52
+
44
53
  ## Usage
45
54
 
46
55
  ### Use as Middleware
@@ -141,17 +150,13 @@ const canActionInScopeMultipleResponse: ScopedActionResponseObject[] =
141
150
  * /
142
151
  ```
143
152
 
144
- **Graph API Routing (v3.3.0+):**
145
-
146
- Starting from version 3.3.0, `canActionInScope` and `canActionInScopeMultiple` can route authorization checks to the Graph API (`authorization-graph` service) instead of the Platform API. This routing is controlled by the Ignite feature flag `navigate-can-action-in-scope-to-graph`.
147
-
148
- - **Feature Flag**: `navigate-can-action-in-scope-to-graph`
149
- - **Default Behavior**: When the feature flag is disabled (default), the SDK routes to Platform API (backward compatible)
150
- - **Graph Routing**: When enabled, authorization checks are routed to the Graph API endpoint `/permissions/is-allowed`
151
- - **Automatic Fallback**: The SDK automatically falls back to Platform API if the feature flag is disabled
152
- - **No Code Changes Required**: The routing is transparent - your code doesn't need to change. Simply upgrade to v3.3.0+ and the feature flag controls the routing behavior
153
+ **Graph API Routing (v3.3.0+)**
153
154
 
154
- The Graph API provides the same authorization results with improved performance and scalability. The feature flag allows for gradual rollout and easy rollback if needed.
155
+ - **Feature Flag**: `navigate-can-action-in-scope-to-graph` must be enabled in Ignite for the specific account/user.
156
+ - **Environment Variable**: `APP_NAME` must be defined (Graph API uses it to sign JWTs). Missing `APP_NAME` throws `GraphApi: APP_NAME environment variable is required for Graph API authentication`.
157
+ - **Routing Logic**: when the flag is released, `canActionInScope` / `canActionInScopeMultiple` call `authorization-graph` (`/permissions/is-allowed`). Otherwise they continue to call Platform API.
158
+ - **Fallback**: If Graph responses are missing permissions, the SDK defaults to `can=false` with `reason.key = 'unknown'`. HTTP errors propagate and are counted in the StatsD error metric.
159
+ - **Migration**: upgrade to v3.3.0+, set `APP_NAME`, and roll out the feature flag gradually—no code changes required for consumers.
155
160
 
156
161
  ### Authorization Attributes API
157
162
 
@@ -10,7 +10,7 @@ export declare class AuthorizationInternalService {
10
10
  static markAuthorized(request: BaseRequest): void;
11
11
  static failIfNotCoveredByAuthorization(request: BaseRequest): void;
12
12
  static throwOnHttpErrorIfNeeded(response: Awaited<ReturnType<typeof fetch>>, placement: string): void;
13
- static throwOnHttpError(status: number, placement: string): void;
13
+ static throwOnHttpError(status: number, placement: string): never;
14
14
  static generateInternalAuthToken(accountId: number, userId: number): string;
15
15
  static setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
16
16
  static getRequestFetchOptions(): MondayFetchOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"authorization-internal-service.d.ts","sourceRoot":"","sources":["../src/authorization-internal-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,OAAO,EAAyB,eAAe,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAK9C,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAO/C,eAAO,MAAM,eAAe,EAAE,eAM7B,CAAC;AAYF,qBAAa,4BAA4B;IACvC,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAQzD,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB;IAO1E,MAAM,CAAC,sBAAsB,IAAI,kBAAkB;IAInD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA2BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CASvC"}
1
+ {"version":3,"file":"authorization-internal-service.d.ts","sourceRoot":"","sources":["../src/authorization-internal-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,OAAO,EAAyB,eAAe,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAK9C,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAO/C,eAAO,MAAM,eAAe,EAAE,eAM7B,CAAC;AAYF,qBAAa,4BAA4B;IACvC,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK;IAQjE,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB;IAO1E,MAAM,CAAC,sBAAsB,IAAI,kBAAkB;IAInD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA2BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CASvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../src/authorization-service.ts"],"names":[],"mappings":"AACA,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;AAG7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAe1C,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;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,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;mBA4DnB,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":"AACA,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;AAG7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAe1C,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;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,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;mBA4CnB,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"}
@@ -117,20 +117,7 @@ class AuthorizationService {
117
117
  let apiType;
118
118
  if (shouldNavigateToGraph) {
119
119
  apiType = 'graph';
120
- try {
121
- scopedActionResponseObjects = await this.graphApi.checkPermissions(accountId, userId, scopedActions);
122
- }
123
- catch (error) {
124
- const status = error instanceof mondayFetchApi.HttpFetcherError ? error.status : undefined;
125
- authorizationInternalService.logger.warn({
126
- tag: 'authorization-service',
127
- error: error instanceof Error ? error.message : String(error),
128
- accountId,
129
- userId,
130
- status,
131
- }, 'Graph API authorization failed');
132
- throw error;
133
- }
120
+ scopedActionResponseObjects = await this.graphApi.checkPermissions(accountId, userId, scopedActions);
134
121
  }
135
122
  else {
136
123
  apiType = 'platform';
@@ -1 +1 @@
1
- {"version":3,"file":"graph-api.d.ts","sourceRoot":"","sources":["../../src/clients/graph-api.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAG3B,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,sBAAsB,EAMvB,MAAM,0BAA0B,CAAC;AASlC;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;;IAezC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAyB/B;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAqCzG;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAiC1B;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAMxC,OAAO,CAAC,MAAM,CAAC,iBAAiB;CAWjC"}
1
+ {"version":3,"file":"graph-api.d.ts","sourceRoot":"","sources":["../../src/clients/graph-api.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAG3B,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,sBAAsB,EAMvB,MAAM,0BAA0B,CAAC;AASlC;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;;IAezC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAyB/B;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAgCzG;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAiC1B;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAMxC,OAAO,CAAC,MAAM,CAAC,iBAAiB;CAWjC"}
@@ -1,14 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const tridentBackendApi = require('@mondaydotcomorg/trident-backend-api');
4
- const mondayFetchApi = require('@mondaydotcomorg/monday-fetch-api');
5
4
  const types_scopedActionsContracts = require('../types/scoped-actions-contracts.js');
6
5
  const authorizationInternalService = require('../authorization-internal-service.js');
7
6
  const attributionsService = require('../attributions-service.js');
8
7
  const utils_authorization_utils = require('../utils/authorization.utils.js');
9
- const metricsService = require('../metrics-service.js');
10
8
  const mondayJwt = require('@mondaydotcomorg/monday-jwt');
11
9
  const constants = require('../constants.js');
10
+ const utils_apiErrorHandler = require('../utils/api-error-handler.js');
12
11
 
13
12
  const CAN_ACTION_IN_SCOPE_GRAPH_PATH = '/permissions/is-allowed';
14
13
  const APP_NAME_REQUIRED_ERROR = 'GraphApi: APP_NAME environment variable is required for Graph API authentication';
@@ -81,13 +80,8 @@ class GraphApi {
81
80
  return response;
82
81
  }
83
82
  catch (err) {
84
- if (err instanceof mondayFetchApi.HttpFetcherError) {
85
- authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
86
- if (scopedActions.length > 0) {
87
- metricsService.recordAuthorizationError('graph', err.status);
88
- }
89
- }
90
- throw err;
83
+ // handleApiError never returns (throws)
84
+ return utils_apiErrorHandler.handleApiError(err, 'graph', 'canActionInScopeMultiple');
91
85
  }
92
86
  }
93
87
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"platform-api.d.ts","sourceRoot":"","sources":["../../src/clients/platform-api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAE7F,OAAO,EAA0B,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAelF;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;;IAUxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAOlC;;OAEG;YACW,gBAAgB;IA0C9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAkB1B;;OAEG;IACG,gBAAgB,CACpB,OAAO,EAAE,eAAe,EACxB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;CAKzC"}
1
+ {"version":3,"file":"platform-api.d.ts","sourceRoot":"","sources":["../../src/clients/platform-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAE7F,OAAO,EAA0B,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAelF;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;;IAUxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAOlC;;OAEG;YACW,gBAAgB;IAqC9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAkB1B;;OAEG;IACG,gBAAgB,CACpB,OAAO,EAAE,eAAe,EACxB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;CAKzC"}
@@ -1,11 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const tridentBackendApi = require('@mondaydotcomorg/trident-backend-api');
4
- const mondayFetchApi = require('@mondaydotcomorg/monday-fetch-api');
5
4
  const authorizationInternalService = require('../authorization-internal-service.js');
6
5
  const attributionsService = require('../attributions-service.js');
7
6
  const utils_authorization_utils = require('../utils/authorization.utils.js');
8
- const metricsService = require('../metrics-service.js');
7
+ const utils_apiErrorHandler = require('../utils/api-error-handler.js');
9
8
 
10
9
  const PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH = '/internal_ms/authorization/can_actions_in_scopes';
11
10
  /**
@@ -55,13 +54,8 @@ class PlatformApi {
55
54
  return response;
56
55
  }
57
56
  catch (err) {
58
- if (err instanceof mondayFetchApi.HttpFetcherError) {
59
- authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
60
- if (scopedActionsPayload.length > 0) {
61
- metricsService.recordAuthorizationError('platform', err.status);
62
- }
63
- }
64
- throw err;
57
+ // handleApiError never returns (throws)
58
+ return utils_apiErrorHandler.handleApiError(err, 'platform', 'canActionInScopeMultiple');
65
59
  }
66
60
  }
67
61
  /**
@@ -10,7 +10,7 @@ export declare class AuthorizationInternalService {
10
10
  static markAuthorized(request: BaseRequest): void;
11
11
  static failIfNotCoveredByAuthorization(request: BaseRequest): void;
12
12
  static throwOnHttpErrorIfNeeded(response: Awaited<ReturnType<typeof fetch>>, placement: string): void;
13
- static throwOnHttpError(status: number, placement: string): void;
13
+ static throwOnHttpError(status: number, placement: string): never;
14
14
  static generateInternalAuthToken(accountId: number, userId: number): string;
15
15
  static setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
16
16
  static getRequestFetchOptions(): MondayFetchOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"authorization-internal-service.d.ts","sourceRoot":"","sources":["../../src/authorization-internal-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,OAAO,EAAyB,eAAe,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAK9C,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAO/C,eAAO,MAAM,eAAe,EAAE,eAM7B,CAAC;AAYF,qBAAa,4BAA4B;IACvC,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAQzD,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB;IAO1E,MAAM,CAAC,sBAAsB,IAAI,kBAAkB;IAInD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA2BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CASvC"}
1
+ {"version":3,"file":"authorization-internal-service.d.ts","sourceRoot":"","sources":["../../src/authorization-internal-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,OAAO,EAAyB,eAAe,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAK9C,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAO/C,eAAO,MAAM,eAAe,EAAE,eAM7B,CAAC;AAYF,qBAAa,4BAA4B;IACvC,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK;IAQjE,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB;IAO1E,MAAM,CAAC,sBAAsB,IAAI,kBAAkB;IAInD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA2BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CASvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../../src/authorization-service.ts"],"names":[],"mappings":"AACA,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;AAG7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAe1C,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;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,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;mBA4DnB,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":"AACA,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;AAG7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAe1C,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;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,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;mBA4CnB,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"}
@@ -115,20 +115,7 @@ class AuthorizationService {
115
115
  let apiType;
116
116
  if (shouldNavigateToGraph) {
117
117
  apiType = 'graph';
118
- try {
119
- scopedActionResponseObjects = await this.graphApi.checkPermissions(accountId, userId, scopedActions);
120
- }
121
- catch (error) {
122
- const status = error instanceof HttpFetcherError ? error.status : undefined;
123
- logger.warn({
124
- tag: 'authorization-service',
125
- error: error instanceof Error ? error.message : String(error),
126
- accountId,
127
- userId,
128
- status,
129
- }, 'Graph API authorization failed');
130
- throw error;
131
- }
118
+ scopedActionResponseObjects = await this.graphApi.checkPermissions(accountId, userId, scopedActions);
132
119
  }
133
120
  else {
134
121
  apiType = 'platform';
@@ -1 +1 @@
1
- {"version":3,"file":"graph-api.d.ts","sourceRoot":"","sources":["../../../src/clients/graph-api.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAG3B,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,sBAAsB,EAMvB,MAAM,0BAA0B,CAAC;AASlC;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;;IAezC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAyB/B;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAqCzG;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAiC1B;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAMxC,OAAO,CAAC,MAAM,CAAC,iBAAiB;CAWjC"}
1
+ {"version":3,"file":"graph-api.d.ts","sourceRoot":"","sources":["../../../src/clients/graph-api.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAG3B,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,sBAAsB,EAMvB,MAAM,0BAA0B,CAAC;AASlC;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;;IAezC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAyB/B;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAgCzG;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAiC1B;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAMxC,OAAO,CAAC,MAAM,CAAC,iBAAiB;CAWjC"}
@@ -1,12 +1,11 @@
1
1
  import { Api } from '@mondaydotcomorg/trident-backend-api';
2
- import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
3
2
  import { PermitTechnicalReason } from '../types/scoped-actions-contracts.mjs';
4
3
  import { AuthorizationInternalService } from '../authorization-internal-service.mjs';
5
4
  import { getAttributionsFromApi } from '../attributions-service.mjs';
6
5
  import { scopeToResource } from '../utils/authorization.utils.mjs';
7
- import { recordAuthorizationError } from '../metrics-service.mjs';
8
6
  import { signAuthorizationHeader } from '@mondaydotcomorg/monday-jwt';
9
7
  import { GRAPH_APP_NAME } from '../constants.mjs';
8
+ import { handleApiError } from '../utils/api-error-handler.mjs';
10
9
 
11
10
  const CAN_ACTION_IN_SCOPE_GRAPH_PATH = '/permissions/is-allowed';
12
11
  const APP_NAME_REQUIRED_ERROR = 'GraphApi: APP_NAME environment variable is required for Graph API authentication';
@@ -79,13 +78,8 @@ class GraphApi {
79
78
  return response;
80
79
  }
81
80
  catch (err) {
82
- if (err instanceof HttpFetcherError) {
83
- AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
84
- if (scopedActions.length > 0) {
85
- recordAuthorizationError('graph', err.status);
86
- }
87
- }
88
- throw err;
81
+ // handleApiError never returns (throws)
82
+ return handleApiError(err, 'graph', 'canActionInScopeMultiple');
89
83
  }
90
84
  }
91
85
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"platform-api.d.ts","sourceRoot":"","sources":["../../../src/clients/platform-api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAE7F,OAAO,EAA0B,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAelF;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;;IAUxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAOlC;;OAEG;YACW,gBAAgB;IA0C9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAkB1B;;OAEG;IACG,gBAAgB,CACpB,OAAO,EAAE,eAAe,EACxB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;CAKzC"}
1
+ {"version":3,"file":"platform-api.d.ts","sourceRoot":"","sources":["../../../src/clients/platform-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAE7F,OAAO,EAA0B,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAelF;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;;IAUxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAOlC;;OAEG;YACW,gBAAgB;IAqC9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAkB1B;;OAEG;IACG,gBAAgB,CACpB,OAAO,EAAE,eAAe,EACxB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;CAKzC"}
@@ -1,9 +1,8 @@
1
1
  import { Api } from '@mondaydotcomorg/trident-backend-api';
2
- import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
3
2
  import { AuthorizationInternalService, logger } from '../authorization-internal-service.mjs';
4
3
  import { getAttributionsFromApi } from '../attributions-service.mjs';
5
4
  import { toSnakeCase, toCamelCase } from '../utils/authorization.utils.mjs';
6
- import { recordAuthorizationError } from '../metrics-service.mjs';
5
+ import { handleApiError } from '../utils/api-error-handler.mjs';
7
6
 
8
7
  const PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH = '/internal_ms/authorization/can_actions_in_scopes';
9
8
  /**
@@ -53,13 +52,8 @@ class PlatformApi {
53
52
  return response;
54
53
  }
55
54
  catch (err) {
56
- if (err instanceof HttpFetcherError) {
57
- AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
58
- if (scopedActionsPayload.length > 0) {
59
- recordAuthorizationError('platform', err.status);
60
- }
61
- }
62
- throw err;
55
+ // handleApiError never returns (throws)
56
+ return handleApiError(err, 'platform', 'canActionInScopeMultiple');
63
57
  }
64
58
  }
65
59
  /**
@@ -35,8 +35,8 @@ function recordAuthorizationTiming(apiType, duration) {
35
35
  try {
36
36
  Metric.distribution(`authorization.authorizationCheck.${apiType}.duration`, duration);
37
37
  }
38
- catch (error) {
39
- logger.warn({ tag: 'metrics-service', error }, 'Failed to record authorization timing');
38
+ catch {
39
+ // ignore metric emission failures
40
40
  }
41
41
  }
42
42
  function recordAuthorizationError(apiType, statusCode) {
@@ -44,10 +44,10 @@ function recordAuthorizationError(apiType, statusCode) {
44
44
  return;
45
45
  }
46
46
  try {
47
- Metric.increment(`authorization.authorizationCheck.${apiType}.error.${statusCode}`);
47
+ Metric.increment(`authorization.authorizationCheck.${apiType}.error`, { statusCode: String(statusCode) }, 1);
48
48
  }
49
- catch (error) {
50
- logger.warn({ tag: 'metrics-service', error }, 'Failed to record authorization error');
49
+ catch {
50
+ // ignore metric emission failures
51
51
  }
52
52
  }
53
53
 
@@ -0,0 +1,2 @@
1
+ export declare function handleApiError(err: unknown, apiType: 'platform' | 'graph', placement: string): never;
2
+ //# sourceMappingURL=api-error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-error-handler.d.ts","sourceRoot":"","sources":["../../../src/utils/api-error-handler.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,CAgBpG"}
@@ -0,0 +1,18 @@
1
+ import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
2
+ import { logger, AuthorizationInternalService } from '../authorization-internal-service.mjs';
3
+ import { recordAuthorizationError } from '../metrics-service.mjs';
4
+
5
+ function handleApiError(err, apiType, placement) {
6
+ if (err instanceof HttpFetcherError) {
7
+ logger.error({ tag: `${apiType}-api`, status: err.status, error: err.message }, `${apiType.charAt(0).toUpperCase() + apiType.slice(1)} API authorization request failed`);
8
+ recordAuthorizationError(apiType, err.status);
9
+ AuthorizationInternalService.throwOnHttpError(err.status, placement);
10
+ }
11
+ else {
12
+ logger.error({ tag: `${apiType}-api`, error: err instanceof Error ? err.message : String(err) }, `${apiType.charAt(0).toUpperCase() + apiType.slice(1)} API authorization request failed`);
13
+ recordAuthorizationError(apiType, 500);
14
+ throw err;
15
+ }
16
+ }
17
+
18
+ export { handleApiError };
@@ -37,8 +37,8 @@ function recordAuthorizationTiming(apiType, duration) {
37
37
  try {
38
38
  mondayObservabilityKit.Metric.distribution(`authorization.authorizationCheck.${apiType}.duration`, duration);
39
39
  }
40
- catch (error) {
41
- authorizationInternalService.logger.warn({ tag: 'metrics-service', error }, 'Failed to record authorization timing');
40
+ catch {
41
+ // ignore metric emission failures
42
42
  }
43
43
  }
44
44
  function recordAuthorizationError(apiType, statusCode) {
@@ -46,10 +46,10 @@ function recordAuthorizationError(apiType, statusCode) {
46
46
  return;
47
47
  }
48
48
  try {
49
- mondayObservabilityKit.Metric.increment(`authorization.authorizationCheck.${apiType}.error.${statusCode}`);
49
+ mondayObservabilityKit.Metric.increment(`authorization.authorizationCheck.${apiType}.error`, { statusCode: String(statusCode) }, 1);
50
50
  }
51
- catch (error) {
52
- authorizationInternalService.logger.warn({ tag: 'metrics-service', error }, 'Failed to record authorization error');
51
+ catch {
52
+ // ignore metric emission failures
53
53
  }
54
54
  }
55
55
 
@@ -0,0 +1,2 @@
1
+ export declare function handleApiError(err: unknown, apiType: 'platform' | 'graph', placement: string): never;
2
+ //# sourceMappingURL=api-error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/api-error-handler.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,CAgBpG"}
@@ -0,0 +1,20 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const mondayFetchApi = require('@mondaydotcomorg/monday-fetch-api');
4
+ const authorizationInternalService = require('../authorization-internal-service.js');
5
+ const metricsService = require('../metrics-service.js');
6
+
7
+ function handleApiError(err, apiType, placement) {
8
+ if (err instanceof mondayFetchApi.HttpFetcherError) {
9
+ authorizationInternalService.logger.error({ tag: `${apiType}-api`, status: err.status, error: err.message }, `${apiType.charAt(0).toUpperCase() + apiType.slice(1)} API authorization request failed`);
10
+ metricsService.recordAuthorizationError(apiType, err.status);
11
+ authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, placement);
12
+ }
13
+ else {
14
+ authorizationInternalService.logger.error({ tag: `${apiType}-api`, error: err instanceof Error ? err.message : String(err) }, `${apiType.charAt(0).toUpperCase() + apiType.slice(1)} API authorization request failed`);
15
+ metricsService.recordAuthorizationError(apiType, 500);
16
+ throw err;
17
+ }
18
+ }
19
+
20
+ exports.handleApiError = handleApiError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mondaydotcomorg/monday-authorization",
3
- "version": "3.3.0-feat-add-graph-api-routing-support-c17713e",
3
+ "version": "3.3.0-feat-add-graph-api-routing-support-5c7bcd4",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "BSD-3-Clause",
@@ -63,7 +63,7 @@ export class AuthorizationInternalService {
63
63
  throw new Error(`AuthorizationService: [${placement}] authorization request failed with status ${status}`);
64
64
  }
65
65
 
66
- static throwOnHttpError(status: number, placement: string) {
66
+ static throwOnHttpError(status: number, placement: string): never {
67
67
  logger.error(
68
68
  { tag: 'authorization-service', placement, status },
69
69
  'AuthorizationService: authorization request failed'
@@ -190,23 +190,7 @@ export class AuthorizationService {
190
190
 
191
191
  if (shouldNavigateToGraph) {
192
192
  apiType = 'graph';
193
-
194
- try {
195
- scopedActionResponseObjects = await this.graphApi.checkPermissions(accountId, userId, scopedActions);
196
- } catch (error) {
197
- const status = error instanceof HttpFetcherError ? error.status : undefined;
198
- logger.warn(
199
- {
200
- tag: 'authorization-service',
201
- error: error instanceof Error ? error.message : String(error),
202
- accountId,
203
- userId,
204
- status,
205
- },
206
- 'Graph API authorization failed'
207
- );
208
- throw error;
209
- }
193
+ scopedActionResponseObjects = await this.graphApi.checkPermissions(accountId, userId, scopedActions);
210
194
  } else {
211
195
  apiType = 'platform';
212
196
  const profile = this.getProfile(accountId, userId);
@@ -1,5 +1,4 @@
1
1
  import { Api, HttpClient } from '@mondaydotcomorg/trident-backend-api';
2
- import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
3
2
  import {
4
3
  ScopedAction,
5
4
  ScopedActionResponseObject,
@@ -18,9 +17,9 @@ import {
18
17
  GraphPermissionReason,
19
18
  } from '../types/graph-api.types';
20
19
  import { scopeToResource } from '../utils/authorization.utils';
21
- import { recordAuthorizationError } from '../metrics-service';
22
20
  import { signAuthorizationHeader } from '@mondaydotcomorg/monday-jwt';
23
21
  import { GRAPH_APP_NAME } from '../constants';
22
+ import { handleApiError } from '../utils/api-error-handler';
24
23
 
25
24
  const CAN_ACTION_IN_SCOPE_GRAPH_PATH = '/permissions/is-allowed';
26
25
  const APP_NAME_REQUIRED_ERROR = 'GraphApi: APP_NAME environment variable is required for Graph API authentication';
@@ -103,13 +102,8 @@ export class GraphApi {
103
102
 
104
103
  return response;
105
104
  } catch (err) {
106
- if (err instanceof HttpFetcherError) {
107
- AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
108
- if (scopedActions.length > 0) {
109
- recordAuthorizationError('graph', err.status);
110
- }
111
- }
112
- throw err;
105
+ // handleApiError never returns (throws)
106
+ return handleApiError(err, 'graph', 'canActionInScopeMultiple');
113
107
  }
114
108
  }
115
109
 
@@ -1,10 +1,9 @@
1
1
  import { Api, HttpClient } from '@mondaydotcomorg/trident-backend-api';
2
- import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
3
2
  import { ScopedAction, ScopedActionResponseObject } from '../types/scoped-actions-contracts';
4
3
  import { AuthorizationInternalService, logger } from '../authorization-internal-service';
5
4
  import { getAttributionsFromApi, PlatformProfile } from '../attributions-service';
6
5
  import { toCamelCase, toSnakeCase } from '../utils/authorization.utils';
7
- import { recordAuthorizationError } from '../metrics-service';
6
+ import { handleApiError } from '../utils/api-error-handler';
8
7
 
9
8
  const PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH = '/internal_ms/authorization/can_actions_in_scopes';
10
9
 
@@ -76,13 +75,8 @@ export class PlatformApi {
76
75
 
77
76
  return response;
78
77
  } catch (err) {
79
- if (err instanceof HttpFetcherError) {
80
- AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
81
- if (scopedActionsPayload.length > 0) {
82
- recordAuthorizationError('platform', err.status);
83
- }
84
- }
85
- throw err;
78
+ // handleApiError never returns (throws)
79
+ return handleApiError(err, 'platform', 'canActionInScopeMultiple');
86
80
  }
87
81
  }
88
82
 
@@ -49,8 +49,8 @@ export function recordAuthorizationTiming(apiType: ApiType, duration: number): v
49
49
 
50
50
  try {
51
51
  Metric.distribution(`authorization.authorizationCheck.${apiType}.duration`, duration);
52
- } catch (error) {
53
- logger.warn({ tag: 'metrics-service', error }, 'Failed to record authorization timing');
52
+ } catch {
53
+ // ignore metric emission failures
54
54
  }
55
55
  }
56
56
 
@@ -60,8 +60,8 @@ export function recordAuthorizationError(apiType: ApiType, statusCode: number):
60
60
  }
61
61
 
62
62
  try {
63
- Metric.increment(`authorization.authorizationCheck.${apiType}.error.${statusCode}`);
64
- } catch (error) {
65
- logger.warn({ tag: 'metrics-service', error }, 'Failed to record authorization error');
63
+ Metric.increment(`authorization.authorizationCheck.${apiType}.error`, { statusCode: String(statusCode) }, 1);
64
+ } catch {
65
+ // ignore metric emission failures
66
66
  }
67
67
  }
@@ -0,0 +1,21 @@
1
+ import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
2
+ import { AuthorizationInternalService, logger } from '../authorization-internal-service';
3
+ import { recordAuthorizationError } from '../metrics-service';
4
+
5
+ export function handleApiError(err: unknown, apiType: 'platform' | 'graph', placement: string): never {
6
+ if (err instanceof HttpFetcherError) {
7
+ logger.error(
8
+ { tag: `${apiType}-api`, status: err.status, error: err.message },
9
+ `${apiType.charAt(0).toUpperCase() + apiType.slice(1)} API authorization request failed`
10
+ );
11
+ recordAuthorizationError(apiType, err.status);
12
+ AuthorizationInternalService.throwOnHttpError(err.status, placement);
13
+ } else {
14
+ logger.error(
15
+ { tag: `${apiType}-api`, error: err instanceof Error ? err.message : String(err) },
16
+ `${apiType.charAt(0).toUpperCase() + apiType.slice(1)} API authorization request failed`
17
+ );
18
+ recordAuthorizationError(apiType, 500);
19
+ throw err;
20
+ }
21
+ }