@mondaydotcomorg/monday-authorization 3.3.1-feature-bashanye-add-membership-create-delete-api-d00c165 → 3.3.1-fix-use-standard-env-var-for-metric-server-host-bd2a88a

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 (40) hide show
  1. package/README.md +4 -125
  2. package/dist/authorization-service.js +1 -1
  3. package/dist/esm/authorization-service.mjs +1 -1
  4. package/dist/esm/index.d.ts +9 -7
  5. package/dist/esm/index.d.ts.map +1 -1
  6. package/dist/esm/index.mjs +14 -8
  7. package/dist/esm/metrics-service.d.ts +7 -4
  8. package/dist/esm/metrics-service.d.ts.map +1 -1
  9. package/dist/esm/metrics-service.mjs +32 -16
  10. package/dist/esm/utils/api-error-handler.d.ts +1 -1
  11. package/dist/esm/utils/api-error-handler.d.ts.map +1 -1
  12. package/dist/esm/utils/api-error-handler.mjs +4 -4
  13. package/dist/index.d.ts +9 -7
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +14 -9
  16. package/dist/metrics-service.d.ts +7 -4
  17. package/dist/metrics-service.d.ts.map +1 -1
  18. package/dist/metrics-service.js +32 -16
  19. package/dist/utils/api-error-handler.d.ts +1 -1
  20. package/dist/utils/api-error-handler.d.ts.map +1 -1
  21. package/dist/utils/api-error-handler.js +4 -4
  22. package/package.json +1 -1
  23. package/src/authorization-service.ts +1 -1
  24. package/src/index.ts +24 -16
  25. package/src/metrics-service.ts +43 -21
  26. package/src/utils/api-error-handler.ts +5 -9
  27. package/dist/esm/memberships.d.ts +0 -30
  28. package/dist/esm/memberships.d.ts.map +0 -1
  29. package/dist/esm/memberships.mjs +0 -98
  30. package/dist/esm/types/memberships.d.ts +0 -42
  31. package/dist/esm/types/memberships.d.ts.map +0 -1
  32. package/dist/esm/types/memberships.mjs +0 -1
  33. package/dist/memberships.d.ts +0 -30
  34. package/dist/memberships.d.ts.map +0 -1
  35. package/dist/memberships.js +0 -100
  36. package/dist/types/memberships.d.ts +0 -42
  37. package/dist/types/memberships.d.ts.map +0 -1
  38. package/dist/types/memberships.js +0 -1
  39. package/src/memberships.ts +0 -111
  40. package/src/types/memberships.ts +0 -47
package/README.md CHANGED
@@ -25,7 +25,7 @@ import * as MondayAuthorization from '@mondaydotcomorg/monday-authorization';
25
25
 
26
26
  ...
27
27
 
28
- await MondayAuthorization.init({
28
+ MondayAuthorization.init({
29
29
  prometheus: getPrometheus(),
30
30
  metrics: {
31
31
  serviceName: process.env.APP_NAME,
@@ -39,7 +39,9 @@ startServer(...)
39
39
  **Recommended** - optionally init authorization with redisClient so the granted feature results will be cached and reduce http calls.
40
40
 
41
41
  - grantedFeatureRedisExpirationInSeconds - (optional), redis TTL for cached granted features, default set to 5 minutes
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`).
42
+ - metrics - (optional), configure internal DataDog/observability integration. Provide either:
43
+ - `metrics.client` with a pre-initialized StatsD client that exposes `distribution` and `increment`.
44
+ - Or the config fields (`serviceName`, `host`, `port`, `disabled`) to let the SDK initialize `@mondaydotcomorg/monday-observability-kit` for you. 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
45
 
44
46
  ### Metrics & Observability
45
47
 
@@ -402,129 +404,6 @@ interface RolesResponse {
402
404
  }
403
405
  ```
404
406
 
405
- ### Memberships API
406
-
407
- The Memberships API allows you to manage memberships (role assignments) for entities on resources. Use `MembershipsService` to create/update and delete memberships synchronously.
408
-
409
- Important note: there is no validations for the user that create/delete memberships on authorization side.
410
- It's on the caller responsibility to validate the user have the right permission to change these memberships.
411
-
412
- #### Create/Update Memberships
413
-
414
- Use `MembershipsService.upsertMemberships` to create or update memberships synchronously:
415
-
416
- ```ts
417
- import { MembershipsService, MembershipForCreate } from '@mondaydotcomorg/monday-authorization';
418
-
419
- const membershipsService = new MembershipsService();
420
- const accountId = 739630;
421
- const memberships: MembershipForCreate[] = [
422
- {
423
- entityId: 123,
424
- entityType: 'user',
425
- resourceId: 456,
426
- resourceType: 'workspace',
427
- roleId: 5,
428
- roleType: 'basic',
429
- addedById: 789,
430
- },
431
- ];
432
-
433
- const response = await membershipsService.upsertMemberships(accountId, memberships);
434
- // Returns: { memberships: Membership[] }
435
- ```
436
-
437
- **Parameters:**
438
-
439
- - `accountId` - The account ID
440
- - `memberships` - Array of `MembershipForCreate` objects
441
-
442
- #### Delete Memberships
443
-
444
- Use `MembershipsService.deleteMemberships` to delete memberships synchronously:
445
-
446
- ```ts
447
- import { MembershipsService, MembershipForDelete } from '@mondaydotcomorg/monday-authorization';
448
-
449
- const membershipsService = new MembershipsService();
450
- const accountId = 739630;
451
- const memberships: MembershipForDelete[] = [
452
- {
453
- entityId: 123,
454
- entityType: 'user',
455
- resourceId: 456,
456
- resourceType: 'workspace',
457
- },
458
- ];
459
-
460
- const response = await membershipsService.deleteMemberships(accountId, memberships);
461
- // Returns: { memberships: Membership[] }
462
- ```
463
-
464
- **Parameters:**
465
-
466
- - `accountId` - The account ID
467
- - `memberships` - Array of `MembershipForDelete` objects
468
-
469
- #### Types
470
-
471
- The following types are available for working with memberships:
472
-
473
- ```ts
474
- import {
475
- MembershipForCreate,
476
- MembershipForDelete,
477
- Membership,
478
- MembershipCreateResponse,
479
- MembershipDeleteResponse,
480
- } from '@mondaydotcomorg/monday-authorization';
481
-
482
- // MembershipForCreate interface
483
- interface MembershipForCreate {
484
- entityId: number;
485
- entityType: string;
486
- resourceId: number;
487
- resourceType: string;
488
- roleId: number;
489
- roleType?: string;
490
- addedById: number;
491
- }
492
-
493
- // MembershipForDelete interface
494
- interface MembershipForDelete {
495
- entityId?: number;
496
- entityType: string;
497
- resourceId?: number;
498
- resourceType: string;
499
- }
500
-
501
- // Membership interface
502
- interface Membership {
503
- id: number;
504
- entityId: number;
505
- entityType: string;
506
- resourceId: number;
507
- resourceType: string;
508
- roleId: number;
509
- roleType: string;
510
- addedById: null | number | undefined;
511
- hops: number;
512
- isNewRecord: boolean;
513
- previousValues: Partial<Membership>;
514
- walVersion: number | null | undefined;
515
- }
516
-
517
- // MembershipCreateResponse interface
518
- interface MembershipCreateResponse {
519
- memberships: Membership[];
520
- }
521
-
522
- // MembershipDeleteResponse interface
523
- interface MembershipDeleteResponse {
524
- memberships: Membership[];
525
- }
526
- ```
527
-
528
407
  ## Development
529
408
 
530
409
  ### Local Development and Testing
@@ -133,7 +133,7 @@ class AuthorizationService {
133
133
  const { resourceType } = utils_authorization_utils.scopeToResource(scope);
134
134
  const isAuthorized = obj.permit.can;
135
135
  prometheusService.sendAuthorizationCheckResponseTimeMetric(resourceType, action, isAuthorized, 200, time);
136
- metricsService.recordAuthorizationTiming(apiType, time, 'canActionInScopeMultiple');
136
+ metricsService.recordAuthorizationTiming(apiType, time);
137
137
  }
138
138
  return scopedActionResponseObjects;
139
139
  }
@@ -131,7 +131,7 @@ class AuthorizationService {
131
131
  const { resourceType } = scopeToResource(scope);
132
132
  const isAuthorized = obj.permit.can;
133
133
  sendAuthorizationCheckResponseTimeMetric(resourceType, action, isAuthorized, 200, time);
134
- recordAuthorizationTiming(apiType, time, 'canActionInScopeMultiple');
134
+ recordAuthorizationTiming(apiType, time);
135
135
  }
136
136
  return scopedActionResponseObjects;
137
137
  }
@@ -1,23 +1,25 @@
1
1
  import { MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
2
+ import { MetricsClient } from './metrics-service';
2
3
  import * as TestKit from './testKit';
4
+ interface MetricsInitOptions {
5
+ client?: MetricsClient;
6
+ serviceName?: string;
7
+ host?: string;
8
+ port?: number;
9
+ disabled?: boolean;
10
+ }
3
11
  export interface InitOptions {
4
12
  prometheus?: any;
5
13
  mondayFetchOptions?: MondayFetchOptions;
6
14
  redisClient?: any;
7
15
  grantedFeatureRedisExpirationInSeconds?: number;
8
- metrics?: {
9
- serviceName?: string;
10
- host?: string;
11
- port?: number;
12
- disabled?: boolean;
13
- };
16
+ metrics?: MetricsInitOptions;
14
17
  }
15
18
  export declare function init(options?: InitOptions): Promise<void>;
16
19
  export { authorizationCheckMiddleware, getAuthorizationMiddleware, skipAuthorizationMiddleware, } from './authorization-middleware';
17
20
  export { AuthorizationService, AuthorizeResponse } from './authorization-service';
18
21
  export { AuthorizationAttributesService } from './authorization-attributes-service';
19
22
  export { RolesService } from './roles-service';
20
- export { MembershipsService } from './memberships';
21
23
  export { AuthorizationObject, Resource, BaseRequest, ResourceGetter, ContextGetter } from './types/general';
22
24
  export { Translation, ScopedAction, ScopedActionResponseObject, ScopedActionPermit, } from './types/scoped-actions-contracts';
23
25
  export { CustomRole, BasicRole, RoleType, RoleCreateRequest, RoleUpdateRequest, RolesResponse } from './types/roles';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAInE,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AAErC,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAChD,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,iBAuBnD;AAED,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,EACL,WAAW,EACX,YAAY,EACZ,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAqB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AAErC,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAChD,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,iBA6BnD;AAED,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,EACL,WAAW,EACX,YAAY,EACZ,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -7,20 +7,26 @@ export { testKit_index as TestKit };
7
7
  export { authorizationCheckMiddleware, getAuthorizationMiddleware, skipAuthorizationMiddleware } from './authorization-middleware.mjs';
8
8
  export { AuthorizationAttributesService } from './authorization-attributes-service.mjs';
9
9
  export { RolesService } from './roles-service.mjs';
10
- export { MembershipsService } from './memberships.mjs';
11
10
  export { RoleType } from './types/roles.mjs';
12
11
 
13
12
  async function init(options = {}) {
14
13
  if (options.prometheus) {
15
14
  setPrometheus(options.prometheus);
16
15
  }
17
- const resolvedDisabled = options.metrics?.disabled ?? ['test', 'development'].includes((process.env.NODE_ENV ?? '').toLowerCase());
18
- initializeMetrics({
19
- serviceName: options.metrics?.serviceName ?? process.env.APP_NAME ?? 'authorization-sdk',
20
- host: options.metrics?.host,
21
- port: options.metrics?.port,
22
- disabled: resolvedDisabled,
23
- });
16
+ if (options.metrics) {
17
+ if (options.metrics.client) {
18
+ initializeMetrics({ client: options.metrics.client });
19
+ }
20
+ else {
21
+ const resolvedDisabled = options.metrics.disabled ?? ['test', 'development'].includes((process.env.NODE_ENV ?? '').toLowerCase());
22
+ initializeMetrics({
23
+ serviceName: options.metrics.serviceName ?? process.env.APP_NAME ?? 'authorization-sdk',
24
+ host: options.metrics.host,
25
+ port: options.metrics.port,
26
+ disabled: resolvedDisabled,
27
+ });
28
+ }
29
+ }
24
30
  if (options.mondayFetchOptions) {
25
31
  setRequestFetchOptions(options.mondayFetchOptions);
26
32
  }
@@ -1,12 +1,15 @@
1
- type ApiType = 'platform' | 'graph' | 'authorization';
1
+ import { Metric } from '@mondaydotcomorg/monday-observability-kit';
2
+ type ApiType = 'platform' | 'graph';
3
+ export type MetricsClient = Pick<typeof Metric, 'distribution' | 'increment'>;
2
4
  interface InitializeMetricsOptions {
3
- serviceName: string;
5
+ client?: MetricsClient;
6
+ serviceName?: string;
4
7
  host?: string;
5
8
  port?: number;
6
9
  disabled?: boolean;
7
10
  }
8
11
  export declare function initializeMetrics(options: InitializeMetricsOptions): void;
9
- export declare function recordAuthorizationTiming(apiType: ApiType, duration: number, placement: string): void;
10
- export declare function recordAuthorizationError(apiType: ApiType, statusCode: number, placement: string): void;
12
+ export declare function recordAuthorizationTiming(apiType: ApiType, duration: number): void;
13
+ export declare function recordAuthorizationError(apiType: ApiType, statusCode: number): void;
11
14
  export {};
12
15
  //# sourceMappingURL=metrics-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"metrics-service.d.ts","sourceRoot":"","sources":["../../src/metrics-service.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,eAAe,CAAC;AAEtD,UAAU,wBAAwB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CA4BzE;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAUrG;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CActG"}
1
+ {"version":3,"file":"metrics-service.d.ts","sourceRoot":"","sources":["../../src/metrics-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,KAAK,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEpC,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,MAAM,EAAE,cAAc,GAAG,WAAW,CAAC,CAAC;AAE9E,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAiCzE;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAmBlF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAmBnF"}
@@ -1,17 +1,21 @@
1
1
  import { Metric } from '@mondaydotcomorg/monday-observability-kit';
2
2
  import { logger } from './authorization-internal-service.mjs';
3
3
 
4
- let initialized = false;
4
+ let metricsClient = null;
5
5
  function initializeMetrics(options) {
6
- if (initialized) {
6
+ if (metricsClient) {
7
+ return;
8
+ }
9
+ if (options.client) {
10
+ metricsClient = options.client;
7
11
  return;
8
12
  }
9
13
  const { serviceName } = options;
10
14
  if (!serviceName) {
11
- logger.warn({ tag: 'metrics-service' }, 'Metrics initialization skipped: serviceName is missing');
15
+ logger.warn({ tag: 'monday-authorization-sdk' }, 'Metrics initialization skipped: serviceName is missing');
12
16
  return;
13
17
  }
14
- const resolvedHost = options.host ?? process.env.DOGSTATSD_HOST ?? 'localhost';
18
+ const resolvedHost = options.host ?? process.env.HOST_IP ?? 'localhost';
15
19
  const envPort = process.env.DOGSTATSD_PORT ? Number(process.env.DOGSTATSD_PORT) : undefined;
16
20
  const resolvedPort = options.port ?? (Number.isFinite(envPort ?? NaN) ? envPort : undefined) ?? 8125;
17
21
  const resolvedDisabled = options.disabled ?? ['test', 'development'].includes((process.env.NODE_ENV ?? '').toLowerCase());
@@ -22,32 +26,44 @@ function initializeMetrics(options) {
22
26
  port: resolvedPort,
23
27
  disabled: resolvedDisabled,
24
28
  });
25
- initialized = true;
29
+ metricsClient = Metric;
26
30
  }
27
31
  catch (error) {
28
- logger.warn({ tag: 'metrics-service', error }, 'Failed to initialize metrics');
32
+ logger.warn({ tag: 'monday-authorization-sdk', error }, 'Failed to initialize metrics');
29
33
  }
30
34
  }
31
- function recordAuthorizationTiming(apiType, duration, placement) {
32
- if (!initialized) {
35
+ function recordAuthorizationTiming(apiType, duration) {
36
+ if (!metricsClient) {
33
37
  return;
34
38
  }
35
39
  try {
36
- Metric.distribution(`authorization.authorizationCheck.${apiType}.${placement}.duration`, duration);
40
+ metricsClient.distribution(`authorization.authorizationCheck.${apiType}.duration`, duration);
37
41
  }
38
- catch {
39
- // ignore metric emission failures
42
+ catch (error) {
43
+ logger.warn({
44
+ tag: 'monday-authorization-sdk',
45
+ metric: 'authorizationCheckDuration',
46
+ apiType,
47
+ duration,
48
+ error,
49
+ }, 'Failed to emit authorization timing metric');
40
50
  }
41
51
  }
42
- function recordAuthorizationError(apiType, statusCode, placement) {
43
- if (!initialized) {
52
+ function recordAuthorizationError(apiType, statusCode) {
53
+ if (!metricsClient) {
44
54
  return;
45
55
  }
46
56
  try {
47
- Metric.increment(`authorization.authorizationCheck.${apiType}.${placement}.error`, { statusCode: String(statusCode) }, 1);
57
+ metricsClient.increment(`authorization.authorizationCheck.${apiType}.error`, { statusCode: String(statusCode) }, 1);
48
58
  }
49
- catch {
50
- // ignore metric emission failures
59
+ catch (error) {
60
+ logger.warn({
61
+ tag: 'monday-authorization-sdk',
62
+ metric: 'authorizationCheckError',
63
+ apiType,
64
+ statusCode,
65
+ error,
66
+ }, 'Failed to emit authorization error metric');
51
67
  }
52
68
  }
53
69
 
@@ -1,2 +1,2 @@
1
- export declare function handleApiError(err: unknown, apiType: 'platform' | 'graph' | 'authorization', placement: string): never;
1
+ export declare function handleApiError(err: unknown, apiType: 'platform' | 'graph', placement: string): never;
2
2
  //# sourceMappingURL=api-error-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-error-handler.d.ts","sourceRoot":"","sources":["../../../src/utils/api-error-handler.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,UAAU,GAAG,OAAO,GAAG,eAAe,EAC/C,SAAS,EAAE,MAAM,GAChB,KAAK,CAgBP"}
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"}
@@ -4,13 +4,13 @@ import { recordAuthorizationError } from '../metrics-service.mjs';
4
4
 
5
5
  function handleApiError(err, apiType, placement) {
6
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 ${placement} request failed`);
8
- recordAuthorizationError(apiType, err.status, placement);
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
9
  AuthorizationInternalService.throwOnHttpError(err.status, placement);
10
10
  }
11
11
  else {
12
- logger.error({ tag: `${apiType}-api`, error: err instanceof Error ? err.message : String(err) }, `${apiType.charAt(0).toUpperCase() + apiType.slice(1)} API ${placement} request failed`);
13
- recordAuthorizationError(apiType, 500, placement);
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
14
  throw err;
15
15
  }
16
16
  }
package/dist/index.d.ts CHANGED
@@ -1,23 +1,25 @@
1
1
  import { MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
2
+ import { MetricsClient } from './metrics-service';
2
3
  import * as TestKit from './testKit';
4
+ interface MetricsInitOptions {
5
+ client?: MetricsClient;
6
+ serviceName?: string;
7
+ host?: string;
8
+ port?: number;
9
+ disabled?: boolean;
10
+ }
3
11
  export interface InitOptions {
4
12
  prometheus?: any;
5
13
  mondayFetchOptions?: MondayFetchOptions;
6
14
  redisClient?: any;
7
15
  grantedFeatureRedisExpirationInSeconds?: number;
8
- metrics?: {
9
- serviceName?: string;
10
- host?: string;
11
- port?: number;
12
- disabled?: boolean;
13
- };
16
+ metrics?: MetricsInitOptions;
14
17
  }
15
18
  export declare function init(options?: InitOptions): Promise<void>;
16
19
  export { authorizationCheckMiddleware, getAuthorizationMiddleware, skipAuthorizationMiddleware, } from './authorization-middleware';
17
20
  export { AuthorizationService, AuthorizeResponse } from './authorization-service';
18
21
  export { AuthorizationAttributesService } from './authorization-attributes-service';
19
22
  export { RolesService } from './roles-service';
20
- export { MembershipsService } from './memberships';
21
23
  export { AuthorizationObject, Resource, BaseRequest, ResourceGetter, ContextGetter } from './types/general';
22
24
  export { Translation, ScopedAction, ScopedActionResponseObject, ScopedActionPermit, } from './types/scoped-actions-contracts';
23
25
  export { CustomRole, BasicRole, RoleType, RoleCreateRequest, RoleUpdateRequest, RolesResponse } from './types/roles';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAInE,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AAErC,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAChD,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,iBAuBnD;AAED,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,EACL,WAAW,EACX,YAAY,EACZ,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAqB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AAErC,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAChD,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,iBA6BnD;AAED,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,EACL,WAAW,EACX,YAAY,EACZ,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -7,20 +7,26 @@ const testKit_index = require('./testKit/index.js');
7
7
  const authorizationMiddleware = require('./authorization-middleware.js');
8
8
  const authorizationAttributesService = require('./authorization-attributes-service.js');
9
9
  const rolesService = require('./roles-service.js');
10
- const memberships = require('./memberships.js');
11
10
  const types_roles = require('./types/roles.js');
12
11
 
13
12
  async function init(options = {}) {
14
13
  if (options.prometheus) {
15
14
  prometheusService.setPrometheus(options.prometheus);
16
15
  }
17
- const resolvedDisabled = options.metrics?.disabled ?? ['test', 'development'].includes((process.env.NODE_ENV ?? '').toLowerCase());
18
- metricsService.initializeMetrics({
19
- serviceName: options.metrics?.serviceName ?? process.env.APP_NAME ?? 'authorization-sdk',
20
- host: options.metrics?.host,
21
- port: options.metrics?.port,
22
- disabled: resolvedDisabled,
23
- });
16
+ if (options.metrics) {
17
+ if (options.metrics.client) {
18
+ metricsService.initializeMetrics({ client: options.metrics.client });
19
+ }
20
+ else {
21
+ const resolvedDisabled = options.metrics.disabled ?? ['test', 'development'].includes((process.env.NODE_ENV ?? '').toLowerCase());
22
+ metricsService.initializeMetrics({
23
+ serviceName: options.metrics.serviceName ?? process.env.APP_NAME ?? 'authorization-sdk',
24
+ host: options.metrics.host,
25
+ port: options.metrics.port,
26
+ disabled: resolvedDisabled,
27
+ });
28
+ }
29
+ }
24
30
  if (options.mondayFetchOptions) {
25
31
  authorizationService.setRequestFetchOptions(options.mondayFetchOptions);
26
32
  }
@@ -38,7 +44,6 @@ exports.getAuthorizationMiddleware = authorizationMiddleware.getAuthorizationMid
38
44
  exports.skipAuthorizationMiddleware = authorizationMiddleware.skipAuthorizationMiddleware;
39
45
  exports.AuthorizationAttributesService = authorizationAttributesService.AuthorizationAttributesService;
40
46
  exports.RolesService = rolesService.RolesService;
41
- exports.MembershipsService = memberships.MembershipsService;
42
47
  Object.defineProperty(exports, 'RoleType', {
43
48
  enumerable: true,
44
49
  get: () => types_roles.RoleType
@@ -1,12 +1,15 @@
1
- type ApiType = 'platform' | 'graph' | 'authorization';
1
+ import { Metric } from '@mondaydotcomorg/monday-observability-kit';
2
+ type ApiType = 'platform' | 'graph';
3
+ export type MetricsClient = Pick<typeof Metric, 'distribution' | 'increment'>;
2
4
  interface InitializeMetricsOptions {
3
- serviceName: string;
5
+ client?: MetricsClient;
6
+ serviceName?: string;
4
7
  host?: string;
5
8
  port?: number;
6
9
  disabled?: boolean;
7
10
  }
8
11
  export declare function initializeMetrics(options: InitializeMetricsOptions): void;
9
- export declare function recordAuthorizationTiming(apiType: ApiType, duration: number, placement: string): void;
10
- export declare function recordAuthorizationError(apiType: ApiType, statusCode: number, placement: string): void;
12
+ export declare function recordAuthorizationTiming(apiType: ApiType, duration: number): void;
13
+ export declare function recordAuthorizationError(apiType: ApiType, statusCode: number): void;
11
14
  export {};
12
15
  //# sourceMappingURL=metrics-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"metrics-service.d.ts","sourceRoot":"","sources":["../src/metrics-service.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,eAAe,CAAC;AAEtD,UAAU,wBAAwB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CA4BzE;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAUrG;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CActG"}
1
+ {"version":3,"file":"metrics-service.d.ts","sourceRoot":"","sources":["../src/metrics-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,KAAK,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEpC,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,MAAM,EAAE,cAAc,GAAG,WAAW,CAAC,CAAC;AAE9E,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAiCzE;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAmBlF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAmBnF"}
@@ -3,17 +3,21 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
3
  const mondayObservabilityKit = require('@mondaydotcomorg/monday-observability-kit');
4
4
  const authorizationInternalService = require('./authorization-internal-service.js');
5
5
 
6
- let initialized = false;
6
+ let metricsClient = null;
7
7
  function initializeMetrics(options) {
8
- if (initialized) {
8
+ if (metricsClient) {
9
+ return;
10
+ }
11
+ if (options.client) {
12
+ metricsClient = options.client;
9
13
  return;
10
14
  }
11
15
  const { serviceName } = options;
12
16
  if (!serviceName) {
13
- authorizationInternalService.logger.warn({ tag: 'metrics-service' }, 'Metrics initialization skipped: serviceName is missing');
17
+ authorizationInternalService.logger.warn({ tag: 'monday-authorization-sdk' }, 'Metrics initialization skipped: serviceName is missing');
14
18
  return;
15
19
  }
16
- const resolvedHost = options.host ?? process.env.DOGSTATSD_HOST ?? 'localhost';
20
+ const resolvedHost = options.host ?? process.env.HOST_IP ?? 'localhost';
17
21
  const envPort = process.env.DOGSTATSD_PORT ? Number(process.env.DOGSTATSD_PORT) : undefined;
18
22
  const resolvedPort = options.port ?? (Number.isFinite(envPort ?? NaN) ? envPort : undefined) ?? 8125;
19
23
  const resolvedDisabled = options.disabled ?? ['test', 'development'].includes((process.env.NODE_ENV ?? '').toLowerCase());
@@ -24,32 +28,44 @@ function initializeMetrics(options) {
24
28
  port: resolvedPort,
25
29
  disabled: resolvedDisabled,
26
30
  });
27
- initialized = true;
31
+ metricsClient = mondayObservabilityKit.Metric;
28
32
  }
29
33
  catch (error) {
30
- authorizationInternalService.logger.warn({ tag: 'metrics-service', error }, 'Failed to initialize metrics');
34
+ authorizationInternalService.logger.warn({ tag: 'monday-authorization-sdk', error }, 'Failed to initialize metrics');
31
35
  }
32
36
  }
33
- function recordAuthorizationTiming(apiType, duration, placement) {
34
- if (!initialized) {
37
+ function recordAuthorizationTiming(apiType, duration) {
38
+ if (!metricsClient) {
35
39
  return;
36
40
  }
37
41
  try {
38
- mondayObservabilityKit.Metric.distribution(`authorization.authorizationCheck.${apiType}.${placement}.duration`, duration);
42
+ metricsClient.distribution(`authorization.authorizationCheck.${apiType}.duration`, duration);
39
43
  }
40
- catch {
41
- // ignore metric emission failures
44
+ catch (error) {
45
+ authorizationInternalService.logger.warn({
46
+ tag: 'monday-authorization-sdk',
47
+ metric: 'authorizationCheckDuration',
48
+ apiType,
49
+ duration,
50
+ error,
51
+ }, 'Failed to emit authorization timing metric');
42
52
  }
43
53
  }
44
- function recordAuthorizationError(apiType, statusCode, placement) {
45
- if (!initialized) {
54
+ function recordAuthorizationError(apiType, statusCode) {
55
+ if (!metricsClient) {
46
56
  return;
47
57
  }
48
58
  try {
49
- mondayObservabilityKit.Metric.increment(`authorization.authorizationCheck.${apiType}.${placement}.error`, { statusCode: String(statusCode) }, 1);
59
+ metricsClient.increment(`authorization.authorizationCheck.${apiType}.error`, { statusCode: String(statusCode) }, 1);
50
60
  }
51
- catch {
52
- // ignore metric emission failures
61
+ catch (error) {
62
+ authorizationInternalService.logger.warn({
63
+ tag: 'monday-authorization-sdk',
64
+ metric: 'authorizationCheckError',
65
+ apiType,
66
+ statusCode,
67
+ error,
68
+ }, 'Failed to emit authorization error metric');
53
69
  }
54
70
  }
55
71
 
@@ -1,2 +1,2 @@
1
- export declare function handleApiError(err: unknown, apiType: 'platform' | 'graph' | 'authorization', placement: string): never;
1
+ export declare function handleApiError(err: unknown, apiType: 'platform' | 'graph', placement: string): never;
2
2
  //# sourceMappingURL=api-error-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/api-error-handler.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,UAAU,GAAG,OAAO,GAAG,eAAe,EAC/C,SAAS,EAAE,MAAM,GAChB,KAAK,CAgBP"}
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"}
@@ -6,13 +6,13 @@ const metricsService = require('../metrics-service.js');
6
6
 
7
7
  function handleApiError(err, apiType, placement) {
8
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 ${placement} request failed`);
10
- metricsService.recordAuthorizationError(apiType, err.status, placement);
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
11
  authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, placement);
12
12
  }
13
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 ${placement} request failed`);
15
- metricsService.recordAuthorizationError(apiType, 500, placement);
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
16
  throw err;
17
17
  }
18
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mondaydotcomorg/monday-authorization",
3
- "version": "3.3.1-feature-bashanye-add-membership-create-delete-api-d00c165",
3
+ "version": "3.3.1-fix-use-standard-env-var-for-metric-server-host-bd2a88a",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "BSD-3-Clause",
@@ -213,7 +213,7 @@ export class AuthorizationService {
213
213
  const { resourceType } = scopeToResource(scope);
214
214
  const isAuthorized = obj.permit.can;
215
215
  sendAuthorizationCheckResponseTimeMetric(resourceType, action, isAuthorized, 200, time);
216
- recordAuthorizationTiming(apiType, time, 'canActionInScopeMultiple');
216
+ recordAuthorizationTiming(apiType, time);
217
217
  }
218
218
 
219
219
  return scopedActionResponseObjects;