@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.
- package/README.md +4 -125
- package/dist/authorization-service.js +1 -1
- package/dist/esm/authorization-service.mjs +1 -1
- package/dist/esm/index.d.ts +9 -7
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.mjs +14 -8
- package/dist/esm/metrics-service.d.ts +7 -4
- package/dist/esm/metrics-service.d.ts.map +1 -1
- package/dist/esm/metrics-service.mjs +32 -16
- package/dist/esm/utils/api-error-handler.d.ts +1 -1
- package/dist/esm/utils/api-error-handler.d.ts.map +1 -1
- package/dist/esm/utils/api-error-handler.mjs +4 -4
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -9
- package/dist/metrics-service.d.ts +7 -4
- package/dist/metrics-service.d.ts.map +1 -1
- package/dist/metrics-service.js +32 -16
- package/dist/utils/api-error-handler.d.ts +1 -1
- package/dist/utils/api-error-handler.d.ts.map +1 -1
- package/dist/utils/api-error-handler.js +4 -4
- package/package.json +1 -1
- package/src/authorization-service.ts +1 -1
- package/src/index.ts +24 -16
- package/src/metrics-service.ts +43 -21
- package/src/utils/api-error-handler.ts +5 -9
- package/dist/esm/memberships.d.ts +0 -30
- package/dist/esm/memberships.d.ts.map +0 -1
- package/dist/esm/memberships.mjs +0 -98
- package/dist/esm/types/memberships.d.ts +0 -42
- package/dist/esm/types/memberships.d.ts.map +0 -1
- package/dist/esm/types/memberships.mjs +0 -1
- package/dist/memberships.d.ts +0 -30
- package/dist/memberships.d.ts.map +0 -1
- package/dist/memberships.js +0 -100
- package/dist/types/memberships.d.ts +0 -42
- package/dist/types/memberships.d.ts.map +0 -1
- package/dist/types/memberships.js +0 -1
- package/src/memberships.ts +0 -111
- 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
|
-
|
|
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.
|
|
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
|
|
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
|
|
134
|
+
recordAuthorizationTiming(apiType, time);
|
|
135
135
|
}
|
|
136
136
|
return scopedActionResponseObjects;
|
|
137
137
|
}
|
package/dist/esm/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';
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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/esm/index.mjs
CHANGED
|
@@ -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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
10
|
-
export declare function recordAuthorizationError(apiType: ApiType, statusCode: number
|
|
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":"
|
|
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
|
|
4
|
+
let metricsClient = null;
|
|
5
5
|
function initializeMetrics(options) {
|
|
6
|
-
if (
|
|
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: '
|
|
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.
|
|
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
|
-
|
|
29
|
+
metricsClient = Metric;
|
|
26
30
|
}
|
|
27
31
|
catch (error) {
|
|
28
|
-
logger.warn({ tag: '
|
|
32
|
+
logger.warn({ tag: 'monday-authorization-sdk', error }, 'Failed to initialize metrics');
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
|
-
function recordAuthorizationTiming(apiType, duration
|
|
32
|
-
if (!
|
|
35
|
+
function recordAuthorizationTiming(apiType, duration) {
|
|
36
|
+
if (!metricsClient) {
|
|
33
37
|
return;
|
|
34
38
|
}
|
|
35
39
|
try {
|
|
36
|
-
|
|
40
|
+
metricsClient.distribution(`authorization.authorizationCheck.${apiType}.duration`, duration);
|
|
37
41
|
}
|
|
38
|
-
catch {
|
|
39
|
-
|
|
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
|
|
43
|
-
if (!
|
|
52
|
+
function recordAuthorizationError(apiType, statusCode) {
|
|
53
|
+
if (!metricsClient) {
|
|
44
54
|
return;
|
|
45
55
|
}
|
|
46
56
|
try {
|
|
47
|
-
|
|
57
|
+
metricsClient.increment(`authorization.authorizationCheck.${apiType}.error`, { statusCode: String(statusCode) }, 1);
|
|
48
58
|
}
|
|
49
|
-
catch {
|
|
50
|
-
|
|
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'
|
|
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,
|
|
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
|
|
8
|
-
recordAuthorizationError(apiType, err.status
|
|
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
|
|
13
|
-
recordAuthorizationError(apiType, 500
|
|
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
10
|
-
export declare function recordAuthorizationError(apiType: ApiType, statusCode: number
|
|
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":"
|
|
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"}
|
package/dist/metrics-service.js
CHANGED
|
@@ -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
|
|
6
|
+
let metricsClient = null;
|
|
7
7
|
function initializeMetrics(options) {
|
|
8
|
-
if (
|
|
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: '
|
|
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.
|
|
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
|
-
|
|
31
|
+
metricsClient = mondayObservabilityKit.Metric;
|
|
28
32
|
}
|
|
29
33
|
catch (error) {
|
|
30
|
-
authorizationInternalService.logger.warn({ tag: '
|
|
34
|
+
authorizationInternalService.logger.warn({ tag: 'monday-authorization-sdk', error }, 'Failed to initialize metrics');
|
|
31
35
|
}
|
|
32
36
|
}
|
|
33
|
-
function recordAuthorizationTiming(apiType, duration
|
|
34
|
-
if (!
|
|
37
|
+
function recordAuthorizationTiming(apiType, duration) {
|
|
38
|
+
if (!metricsClient) {
|
|
35
39
|
return;
|
|
36
40
|
}
|
|
37
41
|
try {
|
|
38
|
-
|
|
42
|
+
metricsClient.distribution(`authorization.authorizationCheck.${apiType}.duration`, duration);
|
|
39
43
|
}
|
|
40
|
-
catch {
|
|
41
|
-
|
|
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
|
|
45
|
-
if (!
|
|
54
|
+
function recordAuthorizationError(apiType, statusCode) {
|
|
55
|
+
if (!metricsClient) {
|
|
46
56
|
return;
|
|
47
57
|
}
|
|
48
58
|
try {
|
|
49
|
-
|
|
59
|
+
metricsClient.increment(`authorization.authorizationCheck.${apiType}.error`, { statusCode: String(statusCode) }, 1);
|
|
50
60
|
}
|
|
51
|
-
catch {
|
|
52
|
-
|
|
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'
|
|
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,
|
|
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
|
|
10
|
-
metricsService.recordAuthorizationError(apiType, err.status
|
|
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
|
|
15
|
-
metricsService.recordAuthorizationError(apiType, 500
|
|
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-
|
|
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
|
|
216
|
+
recordAuthorizationTiming(apiType, time);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
return scopedActionResponseObjects;
|