@mondaydotcomorg/monday-authorization 1.2.19-incr-moshesa-upgrade-to-httpclient-and-use-profile--stubisauthorizedfetch.b83da61 → 1.2.19
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/dist/attributions-service.d.ts +0 -9
- package/dist/attributions-service.d.ts.map +1 -1
- package/dist/attributions-service.js +0 -28
- package/dist/authorization-internal-service.d.ts +0 -4
- package/dist/authorization-internal-service.d.ts.map +1 -1
- package/dist/authorization-internal-service.js +2 -26
- package/dist/authorization-middleware.d.ts.map +1 -1
- package/dist/authorization-service.d.ts.map +1 -1
- package/dist/authorization-service.js +46 -86
- package/dist/esm/attributions-service.d.ts +0 -9
- package/dist/esm/attributions-service.d.ts.map +1 -1
- package/dist/esm/attributions-service.mjs +1 -27
- package/dist/esm/authorization-internal-service.d.ts +0 -4
- package/dist/esm/authorization-internal-service.d.ts.map +1 -1
- package/dist/esm/authorization-internal-service.mjs +3 -26
- package/dist/esm/authorization-middleware.d.ts.map +1 -1
- package/dist/esm/authorization-service.d.ts.map +1 -1
- package/dist/esm/authorization-service.mjs +48 -88
- package/dist/esm/prometheus-service.d.ts +1 -0
- package/dist/esm/prometheus-service.d.ts.map +1 -1
- package/dist/esm/prometheus-service.mjs +18 -1
- package/dist/esm/testKit/index.d.ts.map +1 -1
- package/dist/prometheus-service.d.ts +1 -0
- package/dist/prometheus-service.d.ts.map +1 -1
- package/dist/prometheus-service.js +18 -0
- package/dist/testKit/index.d.ts.map +1 -1
- package/package.json +2 -3
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import { Context, ExecutionContext } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
-
declare enum PlatformProfile {
|
|
3
|
-
API_INTERNAL = "api-internal",
|
|
4
|
-
SLOW = "slow",
|
|
5
|
-
INTERNAL = "internal"
|
|
6
|
-
}
|
|
7
|
-
export declare function getProfile(): PlatformProfile;
|
|
8
|
-
export declare function getExecutionContext(context: Context): ExecutionContext;
|
|
9
1
|
export declare function getAttributionsFromApi(): {
|
|
10
2
|
[key: string]: string;
|
|
11
3
|
};
|
|
12
|
-
export {};
|
|
13
4
|
//# sourceMappingURL=attributions-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributions-service.d.ts","sourceRoot":"","sources":["../src/attributions-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"attributions-service.d.ts","sourceRoot":"","sources":["../src/attributions-service.ts"],"names":[],"mappings":"AASA,wBAAgB,sBAAsB,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAqClE"}
|
|
@@ -7,32 +7,6 @@ const APP_NAME_VARIABLE_KEY = 'APP_NAME';
|
|
|
7
7
|
const APP_NAME_HEADER_NAME = 'x-caller-app-name-from-sdk';
|
|
8
8
|
const FROM_SDK_HEADER_SUFFIX = `-from-sdk`;
|
|
9
9
|
let didSendFailureLogOnce = false;
|
|
10
|
-
var PlatformProfile;
|
|
11
|
-
(function (PlatformProfile) {
|
|
12
|
-
PlatformProfile["API_INTERNAL"] = "api-internal";
|
|
13
|
-
PlatformProfile["SLOW"] = "slow";
|
|
14
|
-
PlatformProfile["INTERNAL"] = "internal";
|
|
15
|
-
})(PlatformProfile || (PlatformProfile = {}));
|
|
16
|
-
function getProfile() {
|
|
17
|
-
const tridentContext = tridentBackendApi.Api.getPart('context');
|
|
18
|
-
if (!tridentContext) {
|
|
19
|
-
return PlatformProfile.INTERNAL;
|
|
20
|
-
}
|
|
21
|
-
const { mondayRequestSource } = getExecutionContext(tridentContext);
|
|
22
|
-
switch (mondayRequestSource) {
|
|
23
|
-
case 'api': {
|
|
24
|
-
return PlatformProfile.API_INTERNAL;
|
|
25
|
-
}
|
|
26
|
-
case 'slow': {
|
|
27
|
-
return PlatformProfile.SLOW;
|
|
28
|
-
}
|
|
29
|
-
default:
|
|
30
|
-
return PlatformProfile.INTERNAL;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function getExecutionContext(context) {
|
|
34
|
-
return context.execution.get();
|
|
35
|
-
}
|
|
36
10
|
function getAttributionsFromApi() {
|
|
37
11
|
const callerAppNameFromSdk = {
|
|
38
12
|
[APP_NAME_HEADER_NAME]: tryJsonParse(getEnvVariable(APP_NAME_VARIABLE_KEY)),
|
|
@@ -79,5 +53,3 @@ function tryJsonParse(value) {
|
|
|
79
53
|
}
|
|
80
54
|
|
|
81
55
|
exports.getAttributionsFromApi = getAttributionsFromApi;
|
|
82
|
-
exports.getExecutionContext = getExecutionContext;
|
|
83
|
-
exports.getProfile = getProfile;
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import { fetch, MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
|
|
2
|
-
import { OnRetryCallback, RetryPolicy } from '@mondaydotcomorg/monday-fetch-api';
|
|
3
2
|
import type { Request } from 'express';
|
|
4
3
|
export declare const logger: import("bunyan");
|
|
5
|
-
export declare const onRetryCallback: OnRetryCallback;
|
|
6
4
|
export declare class AuthorizationInternalService {
|
|
7
5
|
static skipAuthorization(requset: Request): void;
|
|
8
6
|
static markAuthorized(request: Request): void;
|
|
9
7
|
static failIfNotCoveredByAuthorization(request: Request): void;
|
|
10
8
|
static throwOnHttpErrorIfNeeded(response: Awaited<ReturnType<typeof fetch>>, placement: string): void;
|
|
11
|
-
static throwOnHttpError(status: number, placement: string): void;
|
|
12
9
|
static generateInternalAuthToken(accountId: number, userId: number): string;
|
|
13
10
|
static setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
|
|
14
11
|
static getRequestFetchOptions(): MondayFetchOptions;
|
|
15
12
|
static getRequestTimeout(): 60000 | 2000;
|
|
16
|
-
static getRetriesPolicy(): RetryPolicy;
|
|
17
13
|
}
|
|
18
14
|
//# sourceMappingURL=authorization-internal-service.d.ts.map
|
|
@@ -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,
|
|
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,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AASvC,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAY/C,qBAAa,4BAA4B;IACvC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIhD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAM9D,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,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,iBAAiB;CAIzB"}
|
|
@@ -24,21 +24,11 @@ return n;
|
|
|
24
24
|
const MondayLogger__namespace = /*#__PURE__*/_interopNamespace(MondayLogger);
|
|
25
25
|
|
|
26
26
|
const INTERNAL_APP_NAME = 'internal_ms';
|
|
27
|
-
const MAX_RETRIES = 3;
|
|
28
|
-
const RETRY_DELAY_MS = 10;
|
|
29
|
-
const logger = MondayLogger__namespace.getLogger();
|
|
30
27
|
const defaultMondayFetchOptions = {
|
|
31
|
-
retries:
|
|
28
|
+
retries: 3,
|
|
32
29
|
callback: logOnFetchFail,
|
|
33
30
|
};
|
|
34
|
-
const
|
|
35
|
-
if (attempt == MAX_RETRIES) {
|
|
36
|
-
logger.error({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed');
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
logger.info({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed, trying again');
|
|
40
|
-
}
|
|
41
|
-
};
|
|
31
|
+
const logger = MondayLogger__namespace.getLogger();
|
|
42
32
|
function logOnFetchFail(retriesLeft, error) {
|
|
43
33
|
if (retriesLeft == 0) {
|
|
44
34
|
logger.error({ retriesLeft, error }, 'Authorization attempt failed due to network issues');
|
|
@@ -68,10 +58,6 @@ class AuthorizationInternalService {
|
|
|
68
58
|
logger.error({ tag: 'authorization-service', placement, status }, 'AuthorizationService: authorization request failed');
|
|
69
59
|
throw new Error(`AuthorizationService: [${placement}] authorization request failed with status ${status}`);
|
|
70
60
|
}
|
|
71
|
-
static throwOnHttpError(status, placement) {
|
|
72
|
-
logger.error({ tag: 'authorization-service', placement, status }, 'AuthorizationService: authorization request failed');
|
|
73
|
-
throw new Error(`AuthorizationService: [${placement}] authorization request failed with status ${status}`);
|
|
74
|
-
}
|
|
75
61
|
static generateInternalAuthToken(accountId, userId) {
|
|
76
62
|
return mondayJwt.signAuthorizationHeader({ appName: INTERNAL_APP_NAME, accountId, userId });
|
|
77
63
|
}
|
|
@@ -88,17 +74,7 @@ class AuthorizationInternalService {
|
|
|
88
74
|
const isDevEnv = process.env.NODE_ENV === 'development';
|
|
89
75
|
return isDevEnv ? 60000 : 2000;
|
|
90
76
|
}
|
|
91
|
-
static getRetriesPolicy() {
|
|
92
|
-
const fetchOptions = AuthorizationInternalService.getRequestFetchOptions();
|
|
93
|
-
return {
|
|
94
|
-
useRetries: fetchOptions.retries !== undefined,
|
|
95
|
-
maxRetries: fetchOptions.retries !== undefined ? fetchOptions.retries : 0,
|
|
96
|
-
onRetry: onRetryCallback,
|
|
97
|
-
retryDelayMS: fetchOptions.retryDelay ?? RETRY_DELAY_MS,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
77
|
}
|
|
101
78
|
|
|
102
79
|
exports.AuthorizationInternalService = AuthorizationInternalService;
|
|
103
80
|
exports.logger = logger;
|
|
104
|
-
exports.onRetryCallback = onRetryCallback;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-middleware.d.ts","sourceRoot":"","sources":["../src/authorization-middleware.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,SAAS,CAAC;AAIrD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,EAC9B,aAAa,CAAC,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"authorization-middleware.d.ts","sourceRoot":"","sources":["../src/authorization-middleware.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,SAAS,CAAC;AAIrD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,EAC9B,aAAa,CAAC,EAAE,aAAa,aAGlB,WAAW,YACV,YAAY,QAChB,YAAY,KACjB,OAAO,CAAC,IAAI,CAAC,CAYjB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAGlH;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CASnH;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAElE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAS,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAuB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAK7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAM1C,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC7C;AAED,wBAAgB,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB,QAElF;AAED,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAEvD;;;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;WAMjB,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;mBA4CnB,oBAAoB;mBAUpB,oBAAoB;CAiE1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F"}
|
|
@@ -4,8 +4,7 @@ const perf_hooks = require('perf_hooks');
|
|
|
4
4
|
const snakeCase = require('lodash/snakeCase.js');
|
|
5
5
|
const camelCase = require('lodash/camelCase.js');
|
|
6
6
|
const mapKeys = require('lodash/mapKeys.js');
|
|
7
|
-
const
|
|
8
|
-
const mondayFetchApi = require('@mondaydotcomorg/monday-fetch-api');
|
|
7
|
+
const mondayFetch = require('@mondaydotcomorg/monday-fetch');
|
|
9
8
|
const prometheusService = require('./prometheus-service.js');
|
|
10
9
|
const authorizationInternalService = require('./authorization-internal-service.js');
|
|
11
10
|
const attributionsService = require('./attributions-service.js');
|
|
@@ -17,8 +16,6 @@ const camelCase__default = /*#__PURE__*/_interopDefault(camelCase);
|
|
|
17
16
|
const mapKeys__default = /*#__PURE__*/_interopDefault(mapKeys);
|
|
18
17
|
|
|
19
18
|
const GRANTED_FEATURE_CACHE_EXPIRATION_SECONDS = 5 * 60;
|
|
20
|
-
const PLATFORM_AUTHORIZE_PATH = '/internal_ms/authorization/authorize';
|
|
21
|
-
const PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH = '/internal_ms/authorization/can_actions_in_scopes';
|
|
22
19
|
function setRequestFetchOptions(customMondayFetchOptions) {
|
|
23
20
|
authorizationInternalService.AuthorizationInternalService.setRequestFetchOptions(customMondayFetchOptions);
|
|
24
21
|
}
|
|
@@ -78,53 +75,30 @@ class AuthorizationService {
|
|
|
78
75
|
return { ...scopedAction, scope: mapKeys__default.default(scopedAction.scope, (_, key) => snakeCase__default.default(key)) }; // for example: { workspaceId: 1 } => { workspace_id: 1 }
|
|
79
76
|
});
|
|
80
77
|
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
user_id: userId,
|
|
99
|
-
scoped_actions: scopedActionsPayload,
|
|
100
|
-
}),
|
|
101
|
-
}, {
|
|
102
|
-
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
103
|
-
retryPolicy: authorizationInternalService.AuthorizationInternalService.getRetriesPolicy(),
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
catch (err) {
|
|
107
|
-
if (err instanceof mondayFetchApi.HttpFetcherError) {
|
|
108
|
-
authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
throw err;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function toCamelCase(obj) {
|
|
115
|
-
return mapKeys__default.default(obj, (_, key) => camelCase__default.default(key));
|
|
116
|
-
}
|
|
117
|
-
if (!response) {
|
|
118
|
-
authorizationInternalService.logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
|
|
119
|
-
throw new Error('AuthorizationService: missing response');
|
|
120
|
-
}
|
|
121
|
-
const scopedActionsResponseObjects = response.result.map(responseObject => {
|
|
78
|
+
const response = await mondayFetch.fetch(getCanActionsInScopesUrl(), {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: {
|
|
81
|
+
Authorization: internalAuthToken,
|
|
82
|
+
'Content-Type': 'application/json',
|
|
83
|
+
...attributionHeaders,
|
|
84
|
+
},
|
|
85
|
+
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
86
|
+
body: JSON.stringify({
|
|
87
|
+
user_id: userId,
|
|
88
|
+
scoped_actions: scopedActionsPayload,
|
|
89
|
+
}),
|
|
90
|
+
}, authorizationInternalService.AuthorizationInternalService.getRequestFetchOptions());
|
|
91
|
+
authorizationInternalService.AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'canActionInScopeMultiple');
|
|
92
|
+
const responseBody = await response.json();
|
|
93
|
+
const camelCaseKeys = obj => Object.fromEntries(Object.entries(obj).map(([key, value]) => [camelCase__default.default(key), value]));
|
|
94
|
+
const scopedActionsResponseObjects = responseBody.result.map(responseObject => {
|
|
122
95
|
const { scopedAction, permit } = responseObject;
|
|
123
96
|
const { scope } = scopedAction;
|
|
97
|
+
const transformKeys = obj => camelCaseKeys(obj);
|
|
124
98
|
return {
|
|
125
99
|
...responseObject,
|
|
126
|
-
scopedAction: { ...scopedAction, scope:
|
|
127
|
-
permit:
|
|
100
|
+
scopedAction: { ...scopedAction, scope: transformKeys(scope) },
|
|
101
|
+
permit: transformKeys(permit),
|
|
128
102
|
};
|
|
129
103
|
});
|
|
130
104
|
return scopedActionsResponseObjects;
|
|
@@ -137,52 +111,32 @@ class AuthorizationService {
|
|
|
137
111
|
const internalAuthToken = authorizationInternalService.AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
138
112
|
const startTime = perf_hooks.performance.now();
|
|
139
113
|
const attributionHeaders = attributionsService.getAttributionsFromApi();
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
'Content-Type': 'application/json',
|
|
154
|
-
...attributionHeaders,
|
|
155
|
-
},
|
|
156
|
-
body: JSON.stringify({
|
|
157
|
-
user_id: userId,
|
|
158
|
-
authorize_request_objects: authorizationRequestObjects,
|
|
159
|
-
}),
|
|
160
|
-
}, {
|
|
161
|
-
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
162
|
-
retryPolicy: authorizationInternalService.AuthorizationInternalService.getRetriesPolicy(),
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
catch (err) {
|
|
166
|
-
if (err instanceof httpClient.HttpFetcherError) {
|
|
167
|
-
authorizationInternalService.AuthorizationInternalService.throwOnHttpError(err.status, 'isAuthorizedMultiple');
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
throw err;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
114
|
+
const response = await mondayFetch.fetch(getAuthorizeUrl(), {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: {
|
|
117
|
+
Authorization: internalAuthToken,
|
|
118
|
+
'Content-Type': 'application/json',
|
|
119
|
+
...attributionHeaders,
|
|
120
|
+
},
|
|
121
|
+
timeout: authorizationInternalService.AuthorizationInternalService.getRequestTimeout(),
|
|
122
|
+
body: JSON.stringify({
|
|
123
|
+
user_id: userId,
|
|
124
|
+
authorize_request_objects: authorizationRequestObjects,
|
|
125
|
+
}),
|
|
126
|
+
}, authorizationInternalService.AuthorizationInternalService.getRequestFetchOptions());
|
|
173
127
|
const endTime = perf_hooks.performance.now();
|
|
174
128
|
const time = endTime - startTime;
|
|
129
|
+
const responseStatus = response.status;
|
|
130
|
+
prometheusService.sendAuthorizationChecksPerRequestMetric(responseStatus, authorizationRequestObjects.length);
|
|
131
|
+
authorizationInternalService.AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'isAuthorizedMultiple');
|
|
132
|
+
const responseBody = await response.json();
|
|
175
133
|
const unauthorizedObjects = [];
|
|
176
|
-
|
|
177
|
-
authorizationInternalService.logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
|
|
178
|
-
throw new Error('AuthorizationService: missing response');
|
|
179
|
-
}
|
|
180
|
-
response.result.forEach(function (isAuthorized, index) {
|
|
134
|
+
responseBody.result.forEach(function (isAuthorized, index) {
|
|
181
135
|
const authorizationObject = authorizationRequestObjects[index];
|
|
182
136
|
if (!isAuthorized) {
|
|
183
137
|
unauthorizedObjects.push(authorizationObject);
|
|
184
138
|
}
|
|
185
|
-
prometheusService.sendAuthorizationCheckResponseTimeMetric(authorizationObject.resource_type, authorizationObject.action, isAuthorized,
|
|
139
|
+
prometheusService.sendAuthorizationCheckResponseTimeMetric(authorizationObject.resource_type, authorizationObject.action, isAuthorized, responseStatus, time);
|
|
186
140
|
});
|
|
187
141
|
if (unauthorizedObjects.length > 0) {
|
|
188
142
|
authorizationInternalService.logger.info({
|
|
@@ -222,6 +176,12 @@ function createAuthorizationParams(resources, action) {
|
|
|
222
176
|
};
|
|
223
177
|
return params;
|
|
224
178
|
}
|
|
179
|
+
function getAuthorizeUrl() {
|
|
180
|
+
return `${process.env.MONDAY_INTERNAL_URL}/internal_ms/authorization/authorize`;
|
|
181
|
+
}
|
|
182
|
+
function getCanActionsInScopesUrl() {
|
|
183
|
+
return `${process.env.MONDAY_INTERNAL_URL}/internal_ms/authorization/can_actions_in_scopes`;
|
|
184
|
+
}
|
|
225
185
|
|
|
226
186
|
exports.AuthorizationService = AuthorizationService;
|
|
227
187
|
exports.setRedisClient = setRedisClient;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import { Context, ExecutionContext } from '@mondaydotcomorg/trident-backend-api';
|
|
2
|
-
declare enum PlatformProfile {
|
|
3
|
-
API_INTERNAL = "api-internal",
|
|
4
|
-
SLOW = "slow",
|
|
5
|
-
INTERNAL = "internal"
|
|
6
|
-
}
|
|
7
|
-
export declare function getProfile(): PlatformProfile;
|
|
8
|
-
export declare function getExecutionContext(context: Context): ExecutionContext;
|
|
9
1
|
export declare function getAttributionsFromApi(): {
|
|
10
2
|
[key: string]: string;
|
|
11
3
|
};
|
|
12
|
-
export {};
|
|
13
4
|
//# sourceMappingURL=attributions-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributions-service.d.ts","sourceRoot":"","sources":["../../src/attributions-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"attributions-service.d.ts","sourceRoot":"","sources":["../../src/attributions-service.ts"],"names":[],"mappings":"AASA,wBAAgB,sBAAsB,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAqClE"}
|
|
@@ -5,32 +5,6 @@ const APP_NAME_VARIABLE_KEY = 'APP_NAME';
|
|
|
5
5
|
const APP_NAME_HEADER_NAME = 'x-caller-app-name-from-sdk';
|
|
6
6
|
const FROM_SDK_HEADER_SUFFIX = `-from-sdk`;
|
|
7
7
|
let didSendFailureLogOnce = false;
|
|
8
|
-
var PlatformProfile;
|
|
9
|
-
(function (PlatformProfile) {
|
|
10
|
-
PlatformProfile["API_INTERNAL"] = "api-internal";
|
|
11
|
-
PlatformProfile["SLOW"] = "slow";
|
|
12
|
-
PlatformProfile["INTERNAL"] = "internal";
|
|
13
|
-
})(PlatformProfile || (PlatformProfile = {}));
|
|
14
|
-
function getProfile() {
|
|
15
|
-
const tridentContext = Api.getPart('context');
|
|
16
|
-
if (!tridentContext) {
|
|
17
|
-
return PlatformProfile.INTERNAL;
|
|
18
|
-
}
|
|
19
|
-
const { mondayRequestSource } = getExecutionContext(tridentContext);
|
|
20
|
-
switch (mondayRequestSource) {
|
|
21
|
-
case 'api': {
|
|
22
|
-
return PlatformProfile.API_INTERNAL;
|
|
23
|
-
}
|
|
24
|
-
case 'slow': {
|
|
25
|
-
return PlatformProfile.SLOW;
|
|
26
|
-
}
|
|
27
|
-
default:
|
|
28
|
-
return PlatformProfile.INTERNAL;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function getExecutionContext(context) {
|
|
32
|
-
return context.execution.get();
|
|
33
|
-
}
|
|
34
8
|
function getAttributionsFromApi() {
|
|
35
9
|
const callerAppNameFromSdk = {
|
|
36
10
|
[APP_NAME_HEADER_NAME]: tryJsonParse(getEnvVariable(APP_NAME_VARIABLE_KEY)),
|
|
@@ -76,4 +50,4 @@ function tryJsonParse(value) {
|
|
|
76
50
|
}
|
|
77
51
|
}
|
|
78
52
|
|
|
79
|
-
export { getAttributionsFromApi
|
|
53
|
+
export { getAttributionsFromApi };
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import { fetch, MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
|
|
2
|
-
import { OnRetryCallback, RetryPolicy } from '@mondaydotcomorg/monday-fetch-api';
|
|
3
2
|
import type { Request } from 'express';
|
|
4
3
|
export declare const logger: import("bunyan");
|
|
5
|
-
export declare const onRetryCallback: OnRetryCallback;
|
|
6
4
|
export declare class AuthorizationInternalService {
|
|
7
5
|
static skipAuthorization(requset: Request): void;
|
|
8
6
|
static markAuthorized(request: Request): void;
|
|
9
7
|
static failIfNotCoveredByAuthorization(request: Request): void;
|
|
10
8
|
static throwOnHttpErrorIfNeeded(response: Awaited<ReturnType<typeof fetch>>, placement: string): void;
|
|
11
|
-
static throwOnHttpError(status: number, placement: string): void;
|
|
12
9
|
static generateInternalAuthToken(accountId: number, userId: number): string;
|
|
13
10
|
static setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
|
|
14
11
|
static getRequestFetchOptions(): MondayFetchOptions;
|
|
15
12
|
static getRequestTimeout(): 60000 | 2000;
|
|
16
|
-
static getRetriesPolicy(): RetryPolicy;
|
|
17
13
|
}
|
|
18
14
|
//# sourceMappingURL=authorization-internal-service.d.ts.map
|
|
@@ -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,
|
|
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,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AASvC,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAY/C,qBAAa,4BAA4B;IACvC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIhD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAM9D,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,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,iBAAiB;CAIzB"}
|
|
@@ -2,21 +2,11 @@ import { signAuthorizationHeader } from '@mondaydotcomorg/monday-jwt';
|
|
|
2
2
|
import * as MondayLogger from '@mondaydotcomorg/monday-logger';
|
|
3
3
|
|
|
4
4
|
const INTERNAL_APP_NAME = 'internal_ms';
|
|
5
|
-
const MAX_RETRIES = 3;
|
|
6
|
-
const RETRY_DELAY_MS = 10;
|
|
7
|
-
const logger = MondayLogger.getLogger();
|
|
8
5
|
const defaultMondayFetchOptions = {
|
|
9
|
-
retries:
|
|
6
|
+
retries: 3,
|
|
10
7
|
callback: logOnFetchFail,
|
|
11
8
|
};
|
|
12
|
-
const
|
|
13
|
-
if (attempt == MAX_RETRIES) {
|
|
14
|
-
logger.error({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed');
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
logger.info({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed, trying again');
|
|
18
|
-
}
|
|
19
|
-
};
|
|
9
|
+
const logger = MondayLogger.getLogger();
|
|
20
10
|
function logOnFetchFail(retriesLeft, error) {
|
|
21
11
|
if (retriesLeft == 0) {
|
|
22
12
|
logger.error({ retriesLeft, error }, 'Authorization attempt failed due to network issues');
|
|
@@ -46,10 +36,6 @@ class AuthorizationInternalService {
|
|
|
46
36
|
logger.error({ tag: 'authorization-service', placement, status }, 'AuthorizationService: authorization request failed');
|
|
47
37
|
throw new Error(`AuthorizationService: [${placement}] authorization request failed with status ${status}`);
|
|
48
38
|
}
|
|
49
|
-
static throwOnHttpError(status, placement) {
|
|
50
|
-
logger.error({ tag: 'authorization-service', placement, status }, 'AuthorizationService: authorization request failed');
|
|
51
|
-
throw new Error(`AuthorizationService: [${placement}] authorization request failed with status ${status}`);
|
|
52
|
-
}
|
|
53
39
|
static generateInternalAuthToken(accountId, userId) {
|
|
54
40
|
return signAuthorizationHeader({ appName: INTERNAL_APP_NAME, accountId, userId });
|
|
55
41
|
}
|
|
@@ -66,15 +52,6 @@ class AuthorizationInternalService {
|
|
|
66
52
|
const isDevEnv = process.env.NODE_ENV === 'development';
|
|
67
53
|
return isDevEnv ? 60000 : 2000;
|
|
68
54
|
}
|
|
69
|
-
static getRetriesPolicy() {
|
|
70
|
-
const fetchOptions = AuthorizationInternalService.getRequestFetchOptions();
|
|
71
|
-
return {
|
|
72
|
-
useRetries: fetchOptions.retries !== undefined,
|
|
73
|
-
maxRetries: fetchOptions.retries !== undefined ? fetchOptions.retries : 0,
|
|
74
|
-
onRetry: onRetryCallback,
|
|
75
|
-
retryDelayMS: fetchOptions.retryDelay ?? RETRY_DELAY_MS,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
55
|
}
|
|
79
56
|
|
|
80
|
-
export { AuthorizationInternalService, logger
|
|
57
|
+
export { AuthorizationInternalService, logger };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-middleware.d.ts","sourceRoot":"","sources":["../../src/authorization-middleware.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,SAAS,CAAC;AAIrD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,EAC9B,aAAa,CAAC,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"authorization-middleware.d.ts","sourceRoot":"","sources":["../../src/authorization-middleware.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5G,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,SAAS,CAAC;AAIrD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,EAC9B,aAAa,CAAC,EAAE,aAAa,aAGlB,WAAW,YACV,YAAY,QAChB,YAAY,KACjB,OAAO,CAAC,IAAI,CAAC,CAYjB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAGlH;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CASnH;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAElE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../../src/authorization-service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAS,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAuB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAK7F,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAM1C,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC7C;AAED,wBAAgB,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB,QAElF;AAED,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAEvD;;;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;WAMjB,wBAAwB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,0BAA0B,EAAE,CAAC;mBA4CnB,oBAAoB;mBAUpB,oBAAoB;CAiE1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F"}
|
|
@@ -2,15 +2,12 @@ import { performance } from 'perf_hooks';
|
|
|
2
2
|
import snakeCase from 'lodash/snakeCase.js';
|
|
3
3
|
import camelCase from 'lodash/camelCase.js';
|
|
4
4
|
import mapKeys from 'lodash/mapKeys.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { sendAuthorizationCheckResponseTimeMetric } from './prometheus-service.mjs';
|
|
5
|
+
import { fetch } from '@mondaydotcomorg/monday-fetch';
|
|
6
|
+
import { sendAuthorizationChecksPerRequestMetric, sendAuthorizationCheckResponseTimeMetric } from './prometheus-service.mjs';
|
|
8
7
|
import { AuthorizationInternalService, logger } from './authorization-internal-service.mjs';
|
|
9
|
-
import { getAttributionsFromApi
|
|
8
|
+
import { getAttributionsFromApi } from './attributions-service.mjs';
|
|
10
9
|
|
|
11
10
|
const GRANTED_FEATURE_CACHE_EXPIRATION_SECONDS = 5 * 60;
|
|
12
|
-
const PLATFORM_AUTHORIZE_PATH = '/internal_ms/authorization/authorize';
|
|
13
|
-
const PLATFORM_CAN_ACTIONS_IN_SCOPES_PATH = '/internal_ms/authorization/can_actions_in_scopes';
|
|
14
11
|
function setRequestFetchOptions(customMondayFetchOptions) {
|
|
15
12
|
AuthorizationInternalService.setRequestFetchOptions(customMondayFetchOptions);
|
|
16
13
|
}
|
|
@@ -70,53 +67,30 @@ class AuthorizationService {
|
|
|
70
67
|
return { ...scopedAction, scope: mapKeys(scopedAction.scope, (_, key) => snakeCase(key)) }; // for example: { workspaceId: 1 } => { workspace_id: 1 }
|
|
71
68
|
});
|
|
72
69
|
const attributionHeaders = getAttributionsFromApi();
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
user_id: userId,
|
|
91
|
-
scoped_actions: scopedActionsPayload,
|
|
92
|
-
}),
|
|
93
|
-
}, {
|
|
94
|
-
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
95
|
-
retryPolicy: AuthorizationInternalService.getRetriesPolicy(),
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
catch (err) {
|
|
99
|
-
if (err instanceof HttpFetcherError) {
|
|
100
|
-
AuthorizationInternalService.throwOnHttpError(err.status, 'canActionInScopeMultiple');
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
throw err;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
function toCamelCase(obj) {
|
|
107
|
-
return mapKeys(obj, (_, key) => camelCase(key));
|
|
108
|
-
}
|
|
109
|
-
if (!response) {
|
|
110
|
-
logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
|
|
111
|
-
throw new Error('AuthorizationService: missing response');
|
|
112
|
-
}
|
|
113
|
-
const scopedActionsResponseObjects = response.result.map(responseObject => {
|
|
70
|
+
const response = await fetch(getCanActionsInScopesUrl(), {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: {
|
|
73
|
+
Authorization: internalAuthToken,
|
|
74
|
+
'Content-Type': 'application/json',
|
|
75
|
+
...attributionHeaders,
|
|
76
|
+
},
|
|
77
|
+
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
78
|
+
body: JSON.stringify({
|
|
79
|
+
user_id: userId,
|
|
80
|
+
scoped_actions: scopedActionsPayload,
|
|
81
|
+
}),
|
|
82
|
+
}, AuthorizationInternalService.getRequestFetchOptions());
|
|
83
|
+
AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'canActionInScopeMultiple');
|
|
84
|
+
const responseBody = await response.json();
|
|
85
|
+
const camelCaseKeys = obj => Object.fromEntries(Object.entries(obj).map(([key, value]) => [camelCase(key), value]));
|
|
86
|
+
const scopedActionsResponseObjects = responseBody.result.map(responseObject => {
|
|
114
87
|
const { scopedAction, permit } = responseObject;
|
|
115
88
|
const { scope } = scopedAction;
|
|
89
|
+
const transformKeys = obj => camelCaseKeys(obj);
|
|
116
90
|
return {
|
|
117
91
|
...responseObject,
|
|
118
|
-
scopedAction: { ...scopedAction, scope:
|
|
119
|
-
permit:
|
|
92
|
+
scopedAction: { ...scopedAction, scope: transformKeys(scope) },
|
|
93
|
+
permit: transformKeys(permit),
|
|
120
94
|
};
|
|
121
95
|
});
|
|
122
96
|
return scopedActionsResponseObjects;
|
|
@@ -129,52 +103,32 @@ class AuthorizationService {
|
|
|
129
103
|
const internalAuthToken = AuthorizationInternalService.generateInternalAuthToken(accountId, userId);
|
|
130
104
|
const startTime = performance.now();
|
|
131
105
|
const attributionHeaders = getAttributionsFromApi();
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
'Content-Type': 'application/json',
|
|
146
|
-
...attributionHeaders,
|
|
147
|
-
},
|
|
148
|
-
body: JSON.stringify({
|
|
149
|
-
user_id: userId,
|
|
150
|
-
authorize_request_objects: authorizationRequestObjects,
|
|
151
|
-
}),
|
|
152
|
-
}, {
|
|
153
|
-
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
154
|
-
retryPolicy: AuthorizationInternalService.getRetriesPolicy(),
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
catch (err) {
|
|
158
|
-
if (err instanceof httpClient.HttpFetcherError) {
|
|
159
|
-
AuthorizationInternalService.throwOnHttpError(err.status, 'isAuthorizedMultiple');
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
throw err;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
106
|
+
const response = await fetch(getAuthorizeUrl(), {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
Authorization: internalAuthToken,
|
|
110
|
+
'Content-Type': 'application/json',
|
|
111
|
+
...attributionHeaders,
|
|
112
|
+
},
|
|
113
|
+
timeout: AuthorizationInternalService.getRequestTimeout(),
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
user_id: userId,
|
|
116
|
+
authorize_request_objects: authorizationRequestObjects,
|
|
117
|
+
}),
|
|
118
|
+
}, AuthorizationInternalService.getRequestFetchOptions());
|
|
165
119
|
const endTime = performance.now();
|
|
166
120
|
const time = endTime - startTime;
|
|
121
|
+
const responseStatus = response.status;
|
|
122
|
+
sendAuthorizationChecksPerRequestMetric(responseStatus, authorizationRequestObjects.length);
|
|
123
|
+
AuthorizationInternalService.throwOnHttpErrorIfNeeded(response, 'isAuthorizedMultiple');
|
|
124
|
+
const responseBody = await response.json();
|
|
167
125
|
const unauthorizedObjects = [];
|
|
168
|
-
|
|
169
|
-
logger.error({ tag: 'authorization-service', response }, 'AuthorizationService: missing response');
|
|
170
|
-
throw new Error('AuthorizationService: missing response');
|
|
171
|
-
}
|
|
172
|
-
response.result.forEach(function (isAuthorized, index) {
|
|
126
|
+
responseBody.result.forEach(function (isAuthorized, index) {
|
|
173
127
|
const authorizationObject = authorizationRequestObjects[index];
|
|
174
128
|
if (!isAuthorized) {
|
|
175
129
|
unauthorizedObjects.push(authorizationObject);
|
|
176
130
|
}
|
|
177
|
-
sendAuthorizationCheckResponseTimeMetric(authorizationObject.resource_type, authorizationObject.action, isAuthorized,
|
|
131
|
+
sendAuthorizationCheckResponseTimeMetric(authorizationObject.resource_type, authorizationObject.action, isAuthorized, responseStatus, time);
|
|
178
132
|
});
|
|
179
133
|
if (unauthorizedObjects.length > 0) {
|
|
180
134
|
logger.info({
|
|
@@ -214,5 +168,11 @@ function createAuthorizationParams(resources, action) {
|
|
|
214
168
|
};
|
|
215
169
|
return params;
|
|
216
170
|
}
|
|
171
|
+
function getAuthorizeUrl() {
|
|
172
|
+
return `${process.env.MONDAY_INTERNAL_URL}/internal_ms/authorization/authorize`;
|
|
173
|
+
}
|
|
174
|
+
function getCanActionsInScopesUrl() {
|
|
175
|
+
return `${process.env.MONDAY_INTERNAL_URL}/internal_ms/authorization/can_actions_in_scopes`;
|
|
176
|
+
}
|
|
217
177
|
|
|
218
178
|
export { AuthorizationService, setRedisClient, setRequestFetchOptions };
|
|
@@ -6,5 +6,6 @@ export declare const METRICS: {
|
|
|
6
6
|
};
|
|
7
7
|
export declare function setPrometheus(customPrometheus: any): void;
|
|
8
8
|
export declare function getMetricsManager(): any;
|
|
9
|
+
export declare function sendAuthorizationChecksPerRequestMetric(responseStatus: any, amountOfAuthorizationObjects: any): void;
|
|
9
10
|
export declare function sendAuthorizationCheckResponseTimeMetric(resourceType: string, action: Action, isAuthorized: boolean, responseStatus: number, time: number): void;
|
|
10
11
|
//# sourceMappingURL=prometheus-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prometheus-service.d.ts","sourceRoot":"","sources":["../../src/prometheus-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"prometheus-service.d.ts","sourceRoot":"","sources":["../../src/prometheus-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAMzC,eAAO,MAAM,OAAO;;;;CAInB,CAAC;AAcF,wBAAgB,aAAa,CAAC,gBAAgB,KAAA,QAiB7C;AAED,wBAAgB,iBAAiB,QAEhC;AAED,wBAAgB,uCAAuC,CAAC,cAAc,KAAA,EAAE,4BAA4B,KAAA,QAQnG;AAED,wBAAgB,wCAAwC,CACtD,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,OAAO,EACrB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,QASb"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
let prometheus = null;
|
|
2
|
+
let authorizationChecksPerRequestMetric = null;
|
|
2
3
|
let authorizationCheckResponseTimeMetric = null;
|
|
3
4
|
const METRICS = {
|
|
4
5
|
AUTHORIZATION_CHECK: 'authorization_check',
|
|
5
6
|
AUTHORIZATION_CHECKS_PER_REQUEST: 'authorization_checks_per_request',
|
|
6
7
|
AUTHORIZATION_CHECK_RESPONSE_TIME: 'authorization_check_response_time',
|
|
7
8
|
};
|
|
9
|
+
const authorizationChecksPerRequestMetricConfig = {
|
|
10
|
+
name: METRICS.AUTHORIZATION_CHECKS_PER_REQUEST,
|
|
11
|
+
labels: ['responseStatus'],
|
|
12
|
+
description: 'Authorization checks per request summary',
|
|
13
|
+
};
|
|
8
14
|
const authorizationCheckResponseTimeMetricConfig = {
|
|
9
15
|
name: METRICS.AUTHORIZATION_CHECK_RESPONSE_TIME,
|
|
10
16
|
labels: ['resourceType', 'action', 'isAuthorized', 'responseStatus'],
|
|
@@ -13,11 +19,22 @@ const authorizationCheckResponseTimeMetricConfig = {
|
|
|
13
19
|
function setPrometheus(customPrometheus) {
|
|
14
20
|
prometheus = customPrometheus;
|
|
15
21
|
const { METRICS_TYPES } = prometheus;
|
|
22
|
+
authorizationChecksPerRequestMetric = getMetricsManager().addMetric(METRICS_TYPES.SUMMARY, authorizationChecksPerRequestMetricConfig.name, authorizationChecksPerRequestMetricConfig.labels, authorizationChecksPerRequestMetricConfig.description);
|
|
16
23
|
authorizationCheckResponseTimeMetric = getMetricsManager().addMetric(METRICS_TYPES.SUMMARY, authorizationCheckResponseTimeMetricConfig.name, authorizationCheckResponseTimeMetricConfig.labels, authorizationCheckResponseTimeMetricConfig.description);
|
|
17
24
|
}
|
|
18
25
|
function getMetricsManager() {
|
|
19
26
|
return prometheus?.metricsManager;
|
|
20
27
|
}
|
|
28
|
+
function sendAuthorizationChecksPerRequestMetric(responseStatus, amountOfAuthorizationObjects) {
|
|
29
|
+
try {
|
|
30
|
+
if (authorizationChecksPerRequestMetric) {
|
|
31
|
+
authorizationChecksPerRequestMetric.labels(responseStatus).observe(amountOfAuthorizationObjects);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
// ignore
|
|
36
|
+
}
|
|
37
|
+
}
|
|
21
38
|
function sendAuthorizationCheckResponseTimeMetric(resourceType, action, isAuthorized, responseStatus, time) {
|
|
22
39
|
try {
|
|
23
40
|
if (authorizationCheckResponseTimeMetric) {
|
|
@@ -29,4 +46,4 @@ function sendAuthorizationCheckResponseTimeMetric(resourceType, action, isAuthor
|
|
|
29
46
|
}
|
|
30
47
|
}
|
|
31
48
|
|
|
32
|
-
export { METRICS, getMetricsManager, sendAuthorizationCheckResponseTimeMetric, setPrometheus };
|
|
49
|
+
export { METRICS, getMetricsManager, sendAuthorizationCheckResponseTimeMetric, sendAuthorizationChecksPerRequestMetric, setPrometheus };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testKit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG9G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testKit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG9G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,eAAO,MAAM,sBAAsB,cAAe,MAAM,UAAU,MAAM,aAAa,QAAQ,EAAE,UAAU,MAAM,SAE9G,CAAC;AAEF,eAAO,MAAM,yBAAyB,YAErC,CAAC;AAyBF,eAAO,MAAM,8BAA8B,WACjC,MAAM,kBACE,cAAc,kBACd,aAAa,eAGlB,WAAW,YACV,YAAY,QAChB,YAAY,KACjB,OAAO,CAAC,IAAI,CAYhB,CAAC"}
|
|
@@ -6,5 +6,6 @@ export declare const METRICS: {
|
|
|
6
6
|
};
|
|
7
7
|
export declare function setPrometheus(customPrometheus: any): void;
|
|
8
8
|
export declare function getMetricsManager(): any;
|
|
9
|
+
export declare function sendAuthorizationChecksPerRequestMetric(responseStatus: any, amountOfAuthorizationObjects: any): void;
|
|
9
10
|
export declare function sendAuthorizationCheckResponseTimeMetric(resourceType: string, action: Action, isAuthorized: boolean, responseStatus: number, time: number): void;
|
|
10
11
|
//# sourceMappingURL=prometheus-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prometheus-service.d.ts","sourceRoot":"","sources":["../src/prometheus-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"prometheus-service.d.ts","sourceRoot":"","sources":["../src/prometheus-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAMzC,eAAO,MAAM,OAAO;;;;CAInB,CAAC;AAcF,wBAAgB,aAAa,CAAC,gBAAgB,KAAA,QAiB7C;AAED,wBAAgB,iBAAiB,QAEhC;AAED,wBAAgB,uCAAuC,CAAC,cAAc,KAAA,EAAE,4BAA4B,KAAA,QAQnG;AAED,wBAAgB,wCAAwC,CACtD,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,OAAO,EACrB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,QASb"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
let prometheus = null;
|
|
4
|
+
let authorizationChecksPerRequestMetric = null;
|
|
4
5
|
let authorizationCheckResponseTimeMetric = null;
|
|
5
6
|
const METRICS = {
|
|
6
7
|
AUTHORIZATION_CHECK: 'authorization_check',
|
|
7
8
|
AUTHORIZATION_CHECKS_PER_REQUEST: 'authorization_checks_per_request',
|
|
8
9
|
AUTHORIZATION_CHECK_RESPONSE_TIME: 'authorization_check_response_time',
|
|
9
10
|
};
|
|
11
|
+
const authorizationChecksPerRequestMetricConfig = {
|
|
12
|
+
name: METRICS.AUTHORIZATION_CHECKS_PER_REQUEST,
|
|
13
|
+
labels: ['responseStatus'],
|
|
14
|
+
description: 'Authorization checks per request summary',
|
|
15
|
+
};
|
|
10
16
|
const authorizationCheckResponseTimeMetricConfig = {
|
|
11
17
|
name: METRICS.AUTHORIZATION_CHECK_RESPONSE_TIME,
|
|
12
18
|
labels: ['resourceType', 'action', 'isAuthorized', 'responseStatus'],
|
|
@@ -15,11 +21,22 @@ const authorizationCheckResponseTimeMetricConfig = {
|
|
|
15
21
|
function setPrometheus(customPrometheus) {
|
|
16
22
|
prometheus = customPrometheus;
|
|
17
23
|
const { METRICS_TYPES } = prometheus;
|
|
24
|
+
authorizationChecksPerRequestMetric = getMetricsManager().addMetric(METRICS_TYPES.SUMMARY, authorizationChecksPerRequestMetricConfig.name, authorizationChecksPerRequestMetricConfig.labels, authorizationChecksPerRequestMetricConfig.description);
|
|
18
25
|
authorizationCheckResponseTimeMetric = getMetricsManager().addMetric(METRICS_TYPES.SUMMARY, authorizationCheckResponseTimeMetricConfig.name, authorizationCheckResponseTimeMetricConfig.labels, authorizationCheckResponseTimeMetricConfig.description);
|
|
19
26
|
}
|
|
20
27
|
function getMetricsManager() {
|
|
21
28
|
return prometheus?.metricsManager;
|
|
22
29
|
}
|
|
30
|
+
function sendAuthorizationChecksPerRequestMetric(responseStatus, amountOfAuthorizationObjects) {
|
|
31
|
+
try {
|
|
32
|
+
if (authorizationChecksPerRequestMetric) {
|
|
33
|
+
authorizationChecksPerRequestMetric.labels(responseStatus).observe(amountOfAuthorizationObjects);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
// ignore
|
|
38
|
+
}
|
|
39
|
+
}
|
|
23
40
|
function sendAuthorizationCheckResponseTimeMetric(resourceType, action, isAuthorized, responseStatus, time) {
|
|
24
41
|
try {
|
|
25
42
|
if (authorizationCheckResponseTimeMetric) {
|
|
@@ -34,4 +51,5 @@ function sendAuthorizationCheckResponseTimeMetric(resourceType, action, isAuthor
|
|
|
34
51
|
exports.METRICS = METRICS;
|
|
35
52
|
exports.getMetricsManager = getMetricsManager;
|
|
36
53
|
exports.sendAuthorizationCheckResponseTimeMetric = sendAuthorizationCheckResponseTimeMetric;
|
|
54
|
+
exports.sendAuthorizationChecksPerRequestMetric = sendAuthorizationChecksPerRequestMetric;
|
|
37
55
|
exports.setPrometheus = setPrometheus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testKit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG9G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testKit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG9G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,eAAO,MAAM,sBAAsB,cAAe,MAAM,UAAU,MAAM,aAAa,QAAQ,EAAE,UAAU,MAAM,SAE9G,CAAC;AAEF,eAAO,MAAM,yBAAyB,YAErC,CAAC;AAyBF,eAAO,MAAM,8BAA8B,WACjC,MAAM,kBACE,cAAc,kBACd,aAAa,eAGlB,WAAW,YACV,YAAY,QAChB,YAAY,KACjB,OAAO,CAAC,IAAI,CAYhB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mondaydotcomorg/monday-authorization",
|
|
3
|
-
"version": "1.2.19
|
|
3
|
+
"version": "1.2.19",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@mondaydotcomorg/monday-fetch": "^0.0.7",
|
|
23
|
-
"@mondaydotcomorg/monday-fetch-api": "^1.0.2",
|
|
24
23
|
"@mondaydotcomorg/monday-jwt": "^3.0.14",
|
|
25
24
|
"@mondaydotcomorg/monday-logger": "^4.0.11",
|
|
26
25
|
"@mondaydotcomorg/monday-sns": "^1.0.6",
|
|
@@ -38,7 +37,7 @@
|
|
|
38
37
|
"@types/supertest": "^2.0.11",
|
|
39
38
|
"express": "^4.17.1",
|
|
40
39
|
"ioredis": "^5.2.4",
|
|
41
|
-
"ioredis-mock": "^8.
|
|
40
|
+
"ioredis-mock": "^8.2.2",
|
|
42
41
|
"sinon": "9.0.3",
|
|
43
42
|
"supertest": "^6.1.3",
|
|
44
43
|
"typescript": "^5.2.2"
|