@mondaydotcomorg/monday-authorization 3.8.0 → 3.9.4-feat-shaime-fix-timeout-5ff7b3a

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 (52) hide show
  1. package/dist/authorization-internal-service.d.ts +12 -8
  2. package/dist/authorization-internal-service.d.ts.map +1 -1
  3. package/dist/authorization-internal-service.js +141 -25
  4. package/dist/authorization-service.d.ts +2 -2
  5. package/dist/authorization-service.d.ts.map +1 -1
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +0 -5
  8. package/dist/esm/authorization-internal-service.d.ts +12 -8
  9. package/dist/esm/authorization-internal-service.d.ts.map +1 -1
  10. package/dist/esm/authorization-internal-service.mjs +141 -26
  11. package/dist/esm/authorization-service.d.ts +2 -2
  12. package/dist/esm/authorization-service.d.ts.map +1 -1
  13. package/dist/esm/constants.d.ts.map +1 -1
  14. package/dist/esm/constants.mjs +0 -5
  15. package/dist/esm/index.d.ts +2 -2
  16. package/dist/esm/index.d.ts.map +1 -1
  17. package/dist/esm/memberships.d.ts.map +1 -1
  18. package/dist/esm/memberships.mjs +11 -2
  19. package/dist/esm/roles-service.d.ts.map +1 -1
  20. package/dist/esm/roles-service.mjs +6 -1
  21. package/dist/esm/types/fetch-options.d.ts +13 -0
  22. package/dist/esm/types/fetch-options.d.ts.map +1 -0
  23. package/dist/esm/types/fetch-options.mjs +1 -0
  24. package/dist/esm/types/scoped-actions-contracts.d.ts +1 -4
  25. package/dist/esm/types/scoped-actions-contracts.d.ts.map +1 -1
  26. package/dist/esm/utils/assignment-schema.d.ts +7 -7
  27. package/dist/esm/utils/authorization.utils.d.ts.map +1 -1
  28. package/dist/esm/utils/authorization.utils.mjs +0 -3
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/memberships.d.ts.map +1 -1
  32. package/dist/memberships.js +11 -2
  33. package/dist/roles-service.d.ts.map +1 -1
  34. package/dist/roles-service.js +6 -1
  35. package/dist/types/fetch-options.d.ts +13 -0
  36. package/dist/types/fetch-options.d.ts.map +1 -0
  37. package/dist/types/fetch-options.js +1 -0
  38. package/dist/types/scoped-actions-contracts.d.ts +1 -4
  39. package/dist/types/scoped-actions-contracts.d.ts.map +1 -1
  40. package/dist/utils/assignment-schema.d.ts +7 -7
  41. package/dist/utils/authorization.utils.d.ts.map +1 -1
  42. package/dist/utils/authorization.utils.js +0 -3
  43. package/package.json +1 -1
  44. package/src/authorization-internal-service.ts +202 -33
  45. package/src/authorization-service.ts +2 -2
  46. package/src/constants.ts +0 -5
  47. package/src/index.ts +2 -2
  48. package/src/memberships.ts +11 -2
  49. package/src/roles-service.ts +6 -1
  50. package/src/types/fetch-options.ts +18 -0
  51. package/src/types/scoped-actions-contracts.ts +1 -11
  52. package/src/utils/authorization.utils.ts +0 -3
@@ -1,27 +1,31 @@
1
- import { fetch, MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
2
- import { OnRetryCallback, RetryPolicy, RetryDelayCallback } from '@mondaydotcomorg/monday-fetch-api';
1
+ import { OnRetryCallback, Response, RetryPolicy } from '@mondaydotcomorg/monday-fetch-api';
3
2
  import { IgniteClient } from '@mondaydotcomorg/ignite-sdk';
4
3
  import { BaseRequest } from './types/general';
4
+ import type { AuthorizationFetchOptions } from './types/fetch-options';
5
5
  export declare const MAX_RETRIES = 3;
6
6
  export declare const RETRY_DELAY_MS = 20;
7
7
  export declare const logger: import("bunyan");
8
+ export declare const IGNITE_RETRY_CONFIG_KEY = "authorization_retry_config";
8
9
  export declare const onRetryCallback: OnRetryCallback;
9
10
  /**
10
11
  * Exponential backoff retry delay callback
11
- * Calculates delay as: baseDelay * 2^(attemptCount - 1)
12
+ * Calculates delay as: baseDelay * (exponentBase)^(attemptCount - 1) + jitter(min..max)
12
13
  * Example: attempt 1 -> 100ms, attempt 2 -> 200ms, attempt 3 -> 400ms
13
14
  */
14
- export declare const calcDelayDurationInMs: RetryDelayCallback;
15
+ export declare const calcDelayDurationInMs: ({ attemptCount }: {
16
+ attemptCount: number;
17
+ }) => number;
15
18
  export declare class AuthorizationInternalService {
16
- static igniteClient?: IgniteClient;
19
+ static get igniteClient(): IgniteClient | undefined;
20
+ static set igniteClient(client: IgniteClient | undefined);
17
21
  static skipAuthorization(requset: BaseRequest): void;
18
22
  static markAuthorized(request: BaseRequest): void;
19
23
  static failIfNotCoveredByAuthorization(request: BaseRequest): void;
20
- static throwOnHttpErrorIfNeeded(response: Awaited<ReturnType<typeof fetch>>, placement: string): void;
24
+ static throwOnHttpErrorIfNeeded(response: Response, placement: string): void;
21
25
  static throwOnHttpError(status: number, placement: string): never;
22
26
  static generateInternalAuthToken(accountId: number, userId: number): string;
23
- static setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
24
- static getRequestFetchOptions(): MondayFetchOptions;
27
+ static setRequestFetchOptions(customMondayFetchOptions: AuthorizationFetchOptions): void;
28
+ static getRequestFetchOptions(): AuthorizationFetchOptions;
25
29
  static setIgniteClient(client: IgniteClient): void;
26
30
  static getRequestTimeout(): number;
27
31
  static getRetriesPolicy(): RetryPolicy;
@@ -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,EAEL,eAAe,EACf,WAAW,EACX,kBAAkB,EACnB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAO/C,eAAO,MAAM,eAAe,EAAE,eAM7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAEnC,CAAC;AAYF,qBAAa,4BAA4B;IACvC,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK;IAQjE,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB;IAO1E,MAAM,CAAC,sBAAsB,IAAI,kBAAkB;IAInD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA2BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CAUvC"}
1
+ {"version":3,"file":"authorization-internal-service.d.ts","sourceRoot":"","sources":["../src/authorization-internal-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,eAAe,EACf,QAAQ,EACR,WAAW,EAEZ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAGvE,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAE/C,eAAO,MAAM,uBAAuB,+BAA+B,CAAC;AA4IpE,eAAO,MAAM,eAAe,EAAE,eAkB7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,kBAAkB;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,KAAG,MAOlF,CAAC;AAMF,qBAAa,4BAA4B;IACvC,MAAM,KAAK,YAAY,IAAI,YAAY,GAAG,SAAS,CAElD;IAED,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,EAEvD;IACD,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAc5E,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK;IAQjE,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,yBAAyB;IAWjF,MAAM,CAAC,sBAAsB,IAAI,yBAAyB;IAI1D,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA0BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CAuBvC"}
@@ -27,37 +27,137 @@ const INTERNAL_APP_NAME = 'internal_ms';
27
27
  const MAX_RETRIES = 3;
28
28
  const RETRY_DELAY_MS = 20;
29
29
  const logger = MondayLogger__namespace.getLogger();
30
- const defaultMondayFetchOptions = {
30
+ const IGNITE_RETRY_CONFIG_KEY = 'authorization_retry_config';
31
+ let igniteClient;
32
+ const defaultRetryConfig = {
31
33
  retries: MAX_RETRIES,
32
- callback: logOnFetchFail,
34
+ baseDelayMs: RETRY_DELAY_MS,
35
+ exponentBase: 2,
36
+ jitterMinMs: 0,
37
+ jitterMaxMs: 1000,
38
+ retryOnStatusPatterns: ['429', '5**'],
33
39
  };
34
- const onRetryCallback = (attempt, error) => {
35
- if (attempt == MAX_RETRIES) {
36
- logger.error({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed');
40
+ /**
41
+ * Sanitizes retry configuration values to ensure they are within valid ranges
42
+ */
43
+ function sanitizeRetryConfig(config) {
44
+ return {
45
+ ...config,
46
+ retries: Math.max(0, Math.min(5, config.retries)),
47
+ exponentBase: Math.max(1, Math.min(100, config.exponentBase)),
48
+ jitterMinMs: Math.max(0, config.jitterMinMs),
49
+ };
50
+ }
51
+ function getRetryConfig() {
52
+ if (!igniteClient) {
53
+ return defaultRetryConfig;
54
+ }
55
+ try {
56
+ const config = igniteClient.configuration.getObjectValue(IGNITE_RETRY_CONFIG_KEY, defaultRetryConfig);
57
+ return sanitizeRetryConfig(config);
58
+ }
59
+ catch (error) {
60
+ logger.error({ tag: 'authorization-service', error, key: IGNITE_RETRY_CONFIG_KEY, defaultValue: defaultRetryConfig }, 'Failed to get ignite retry config, using defaults');
61
+ return defaultRetryConfig;
62
+ }
63
+ }
64
+ function randomIntInclusive(min, max) {
65
+ if (max <= min) {
66
+ return min;
67
+ }
68
+ return Math.floor(min + Math.random() * (max - min + 1));
69
+ }
70
+ function buildHttpStatusMatchers(patterns) {
71
+ const matchers = [];
72
+ const addWildcardMatcher = (wildcard) => {
73
+ // Normalized 3-char pattern with digits or '*'
74
+ matchers.push((status) => {
75
+ const s = String(status);
76
+ if (s.length !== 3) {
77
+ return false;
78
+ }
79
+ for (let i = 0; i < 3; i++) {
80
+ const w = wildcard[i];
81
+ const c = s[i];
82
+ if (w === '*') {
83
+ continue;
84
+ }
85
+ if (w !== c) {
86
+ return false;
87
+ }
88
+ }
89
+ return true;
90
+ });
91
+ };
92
+ for (const raw of patterns ?? []) {
93
+ const p = String(raw).trim();
94
+ if (!p) {
95
+ continue;
96
+ }
97
+ // Exact numeric status (e.g. "429")
98
+ if (/^\d+$/.test(p)) {
99
+ const exact = Number(p);
100
+ if (Number.isFinite(exact)) {
101
+ matchers.push((status) => status === exact);
102
+ }
103
+ continue;
104
+ }
105
+ // Wildcards for 3-digit HTTP codes:
106
+ // - "5**" => 5xx
107
+ // - "5*9" => 5?9
108
+ if (/^[0-9*]+$/.test(p) && p.includes('*')) {
109
+ const normalized = p.length < 3 ? p.padEnd(3, '*') : p;
110
+ if (normalized.length !== 3) {
111
+ logger.warn({ tag: 'authorization-service', pattern: p }, 'Invalid retry status wildcard pattern (expected a 3-character pattern like "5**" or "5*9")');
112
+ }
113
+ else {
114
+ addWildcardMatcher(normalized);
115
+ }
116
+ continue;
117
+ }
118
+ logger.warn({ tag: 'authorization-service', pattern: p }, 'Invalid retry status pattern (supported: exact code like "429" or wildcard like "5**")');
119
+ }
120
+ return matchers;
121
+ }
122
+ function shouldRetryOnResponseStatus(responseOrStatus, statusMatchers) {
123
+ const status = responseOrStatus?.status;
124
+ if (typeof status !== 'number') {
125
+ return false;
126
+ }
127
+ return statusMatchers.some(matcher => matcher(status));
128
+ }
129
+ const onRetryCallback = (attempt, error, response, isTimeoutError) => {
130
+ const effectiveMaxRetries = getRetryConfig().retries;
131
+ if (attempt == effectiveMaxRetries) {
132
+ logger.error({ tag: 'authorization-service', attempt, error, response, isTimeoutError }, 'Authorization attempt failed');
37
133
  }
38
134
  else {
39
- logger.info({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed, trying again');
135
+ logger.info({ tag: 'authorization-service', attempt, error, response, isTimeoutError }, 'Authorization attempt failed, trying again');
40
136
  }
41
137
  };
42
138
  /**
43
139
  * Exponential backoff retry delay callback
44
- * Calculates delay as: baseDelay * 2^(attemptCount - 1)
140
+ * Calculates delay as: baseDelay * (exponentBase)^(attemptCount - 1) + jitter(min..max)
45
141
  * Example: attempt 1 -> 100ms, attempt 2 -> 200ms, attempt 3 -> 400ms
46
142
  */
47
143
  const calcDelayDurationInMs = ({ attemptCount }) => {
48
- return RETRY_DELAY_MS * Math.pow(2, attemptCount - 1);
144
+ const { baseDelayMs, exponentBase, jitterMinMs, jitterMaxMs } = getRetryConfig();
145
+ const jitterMin = Math.min(jitterMinMs, jitterMaxMs);
146
+ const jitterMax = Math.max(jitterMinMs, jitterMaxMs);
147
+ const expDelay = baseDelayMs * Math.pow(exponentBase, attemptCount - 1);
148
+ const jitter = randomIntInclusive(jitterMin, jitterMax);
149
+ return expDelay + jitter;
49
150
  };
50
- function logOnFetchFail(retriesLeft, error) {
51
- if (retriesLeft == 0) {
52
- logger.error({ retriesLeft, error }, `Authorization attempt failed due to ${error.message}`);
151
+ let mondayFetchOptions = {
152
+ retries: defaultRetryConfig.retries,
153
+ };
154
+ class AuthorizationInternalService {
155
+ static get igniteClient() {
156
+ return igniteClient;
53
157
  }
54
- else {
55
- logger.info({ retriesLeft, error }, `Authorization attempt failed due to ${error.message}, trying again`);
158
+ static set igniteClient(client) {
159
+ igniteClient = client;
56
160
  }
57
- }
58
- let mondayFetchOptions = defaultMondayFetchOptions;
59
- class AuthorizationInternalService {
60
- static igniteClient;
61
161
  static skipAuthorization(requset) {
62
162
  requset.authorizationSkipPerformed = true;
63
163
  }
@@ -85,16 +185,20 @@ class AuthorizationInternalService {
85
185
  return mondayJwt.signAuthorizationHeader({ appName: INTERNAL_APP_NAME, accountId, userId });
86
186
  }
87
187
  static setRequestFetchOptions(customMondayFetchOptions) {
188
+ const sanitizedOptions = { ...customMondayFetchOptions };
189
+ if (sanitizedOptions.retries !== undefined) {
190
+ sanitizedOptions.retries = Math.max(0, Math.min(5, sanitizedOptions.retries));
191
+ }
88
192
  mondayFetchOptions = {
89
- ...defaultMondayFetchOptions,
90
- ...customMondayFetchOptions,
193
+ ...defaultRetryConfig,
194
+ ...sanitizedOptions,
91
195
  };
92
196
  }
93
197
  static getRequestFetchOptions() {
94
198
  return mondayFetchOptions;
95
199
  }
96
200
  static setIgniteClient(client) {
97
- this.igniteClient = client;
201
+ igniteClient = client;
98
202
  }
99
203
  static getRequestTimeout() {
100
204
  const isDevEnv = process.env.NODE_ENV === 'development';
@@ -118,17 +222,29 @@ class AuthorizationInternalService {
118
222
  }
119
223
  static getRetriesPolicy() {
120
224
  const fetchOptions = AuthorizationInternalService.getRequestFetchOptions();
121
- const retryDelayMS = calcDelayDurationInMs;
225
+ const retryConfig = getRetryConfig();
226
+ const statusMatchers = buildHttpStatusMatchers(retryConfig.retryOnStatusPatterns);
227
+ const defaultRetryOn = (_attempt, _error, response, isTimeoutError) => {
228
+ return isTimeoutError ? true : shouldRetryOnResponseStatus(response ?? undefined, statusMatchers);
229
+ };
230
+ // Sanitize retries from fetchOptions: clamp between 0 and 5
231
+ const rawMaxRetries = fetchOptions?.retries ?? retryConfig.retries;
232
+ const effectiveMaxRetries = Math.max(0, Math.min(5, rawMaxRetries));
233
+ const defaultGetTimeout = timeoutsCount => calcDelayDurationInMs({ attemptCount: timeoutsCount }) + AuthorizationInternalService.getRequestTimeout();
122
234
  return {
123
- useRetries: !!fetchOptions.retries,
124
- maxRetries: fetchOptions.retries ?? 0,
125
- onRetry: onRetryCallback,
126
- retryDelayMS,
235
+ useRetries: fetchOptions?.useRetries ?? true,
236
+ maxRetries: effectiveMaxRetries,
237
+ retryDelayMS: fetchOptions?.retryDelayMS ?? calcDelayDurationInMs,
238
+ onRetry: fetchOptions?.callback ?? onRetryCallback,
239
+ retryOn: fetchOptions?.retryOn ?? defaultRetryOn,
240
+ timeoutRetries: fetchOptions?.timeoutRetries ?? effectiveMaxRetries,
241
+ getTimeout: fetchOptions?.getTimeout ?? defaultGetTimeout,
127
242
  };
128
243
  }
129
244
  }
130
245
 
131
246
  exports.AuthorizationInternalService = AuthorizationInternalService;
247
+ exports.IGNITE_RETRY_CONFIG_KEY = IGNITE_RETRY_CONFIG_KEY;
132
248
  exports.MAX_RETRIES = MAX_RETRIES;
133
249
  exports.RETRY_DELAY_MS = RETRY_DELAY_MS;
134
250
  exports.calcDelayDurationInMs = calcDelayDurationInMs;
@@ -1,13 +1,13 @@
1
- import { MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
2
1
  import { IgniteClient } from '@mondaydotcomorg/ignite-sdk';
3
2
  import { Action, AuthorizationObject, AuthorizationParams, AuthorizationResource } from './types/general';
4
3
  import { ScopedAction, ScopedActionPermit, ScopedActionResponseObject, ScopeOptions } from './types/scoped-actions-contracts';
4
+ import { AuthorizationFetchOptions } from './types/fetch-options';
5
5
  export interface AuthorizeResponse {
6
6
  isAuthorized: boolean;
7
7
  unauthorizedIds?: number[];
8
8
  unauthorizedObjects?: AuthorizationObject[];
9
9
  }
10
- export declare function setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
10
+ export declare function setRequestFetchOptions(customMondayFetchOptions: AuthorizationFetchOptions): void;
11
11
  export declare class AuthorizationService {
12
12
  private static get graphApi();
13
13
  private static _graphApi?;
@@ -1 +1 @@
1
- {"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../src/authorization-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG1G,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAY1C,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC7C;AAED,wBAAgB,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB,QAElF;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IACvD,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC;;;OAGG;WACU,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,qBAAqB,EAAE,EAClC,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;CAmF1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F;AAED,wBAAsB,eAAe,kBAMpC;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAiBjH"}
1
+ {"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../src/authorization-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG1G,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAM1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAOlE,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,yBAAyB,QAEzF;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IACvD,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC;;;OAGG;WACU,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,qBAAqB,EAAE,EAClC,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;CAmF1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F;AAED,wBAAsB,eAAe,kBAMpC;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAiBjH"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AACxC,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD,oBAAY,eAAe;IACzB,UAAU,mCAAmC;CAC9C;AAED,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAUjE,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AACxC,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD,oBAAY,eAAe;IACzB,UAAU,mCAAmC;CAC9C;AAED,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAKjE,CAAC"}
package/dist/constants.js CHANGED
@@ -11,11 +11,6 @@ const ERROR_MESSAGES = {
11
11
  REQUEST_FAILED: (method, status, reason) => `MondayAuthorization: [${method}] request failed with status ${status} with reason: ${reason}`,
12
12
  };
13
13
  const DEFAULT_FETCH_OPTIONS = {
14
- retryPolicy: {
15
- useRetries: true,
16
- maxRetries: 3,
17
- retryDelayMS: 10,
18
- },
19
14
  logPolicy: {
20
15
  logErrors: 'error',
21
16
  logRequests: 'info',
@@ -1,27 +1,31 @@
1
- import { fetch, MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
2
- import { OnRetryCallback, RetryPolicy, RetryDelayCallback } from '@mondaydotcomorg/monday-fetch-api';
1
+ import { OnRetryCallback, Response, RetryPolicy } from '@mondaydotcomorg/monday-fetch-api';
3
2
  import { IgniteClient } from '@mondaydotcomorg/ignite-sdk';
4
3
  import { BaseRequest } from './types/general';
4
+ import type { AuthorizationFetchOptions } from './types/fetch-options';
5
5
  export declare const MAX_RETRIES = 3;
6
6
  export declare const RETRY_DELAY_MS = 20;
7
7
  export declare const logger: import("bunyan");
8
+ export declare const IGNITE_RETRY_CONFIG_KEY = "authorization_retry_config";
8
9
  export declare const onRetryCallback: OnRetryCallback;
9
10
  /**
10
11
  * Exponential backoff retry delay callback
11
- * Calculates delay as: baseDelay * 2^(attemptCount - 1)
12
+ * Calculates delay as: baseDelay * (exponentBase)^(attemptCount - 1) + jitter(min..max)
12
13
  * Example: attempt 1 -> 100ms, attempt 2 -> 200ms, attempt 3 -> 400ms
13
14
  */
14
- export declare const calcDelayDurationInMs: RetryDelayCallback;
15
+ export declare const calcDelayDurationInMs: ({ attemptCount }: {
16
+ attemptCount: number;
17
+ }) => number;
15
18
  export declare class AuthorizationInternalService {
16
- static igniteClient?: IgniteClient;
19
+ static get igniteClient(): IgniteClient | undefined;
20
+ static set igniteClient(client: IgniteClient | undefined);
17
21
  static skipAuthorization(requset: BaseRequest): void;
18
22
  static markAuthorized(request: BaseRequest): void;
19
23
  static failIfNotCoveredByAuthorization(request: BaseRequest): void;
20
- static throwOnHttpErrorIfNeeded(response: Awaited<ReturnType<typeof fetch>>, placement: string): void;
24
+ static throwOnHttpErrorIfNeeded(response: Response, placement: string): void;
21
25
  static throwOnHttpError(status: number, placement: string): never;
22
26
  static generateInternalAuthToken(accountId: number, userId: number): string;
23
- static setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
24
- static getRequestFetchOptions(): MondayFetchOptions;
27
+ static setRequestFetchOptions(customMondayFetchOptions: AuthorizationFetchOptions): void;
28
+ static getRequestFetchOptions(): AuthorizationFetchOptions;
25
29
  static setIgniteClient(client: IgniteClient): void;
26
30
  static getRequestTimeout(): number;
27
31
  static getRetriesPolicy(): RetryPolicy;
@@ -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,EAEL,eAAe,EACf,WAAW,EACX,kBAAkB,EACnB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAO/C,eAAO,MAAM,eAAe,EAAE,eAM7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAEnC,CAAC;AAYF,qBAAa,4BAA4B;IACvC,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAcrG,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK;IAQjE,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB;IAO1E,MAAM,CAAC,sBAAsB,IAAI,kBAAkB;IAInD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA2BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CAUvC"}
1
+ {"version":3,"file":"authorization-internal-service.d.ts","sourceRoot":"","sources":["../../src/authorization-internal-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,eAAe,EACf,QAAQ,EACR,WAAW,EAEZ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAGvE,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,MAAM,kBAA2B,CAAC;AAE/C,eAAO,MAAM,uBAAuB,+BAA+B,CAAC;AA4IpE,eAAO,MAAM,eAAe,EAAE,eAkB7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,kBAAkB;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,KAAG,MAOlF,CAAC;AAMF,qBAAa,4BAA4B;IACvC,MAAM,KAAK,YAAY,IAAI,YAAY,GAAG,SAAS,CAElD;IAED,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,EAEvD;IACD,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjD,MAAM,CAAC,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAMlE,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAc5E,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK;IAQjE,MAAM,CAAC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIlE,MAAM,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,yBAAyB;IAWjF,MAAM,CAAC,sBAAsB,IAAI,yBAAyB;IAI1D,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY;IAI3C,MAAM,CAAC,iBAAiB;IA0BxB,MAAM,CAAC,gBAAgB,IAAI,WAAW;CAuBvC"}
@@ -5,37 +5,137 @@ const INTERNAL_APP_NAME = 'internal_ms';
5
5
  const MAX_RETRIES = 3;
6
6
  const RETRY_DELAY_MS = 20;
7
7
  const logger = MondayLogger.getLogger();
8
- const defaultMondayFetchOptions = {
8
+ const IGNITE_RETRY_CONFIG_KEY = 'authorization_retry_config';
9
+ let igniteClient;
10
+ const defaultRetryConfig = {
9
11
  retries: MAX_RETRIES,
10
- callback: logOnFetchFail,
12
+ baseDelayMs: RETRY_DELAY_MS,
13
+ exponentBase: 2,
14
+ jitterMinMs: 0,
15
+ jitterMaxMs: 1000,
16
+ retryOnStatusPatterns: ['429', '5**'],
11
17
  };
12
- const onRetryCallback = (attempt, error) => {
13
- if (attempt == MAX_RETRIES) {
14
- logger.error({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed');
18
+ /**
19
+ * Sanitizes retry configuration values to ensure they are within valid ranges
20
+ */
21
+ function sanitizeRetryConfig(config) {
22
+ return {
23
+ ...config,
24
+ retries: Math.max(0, Math.min(5, config.retries)),
25
+ exponentBase: Math.max(1, Math.min(100, config.exponentBase)),
26
+ jitterMinMs: Math.max(0, config.jitterMinMs),
27
+ };
28
+ }
29
+ function getRetryConfig() {
30
+ if (!igniteClient) {
31
+ return defaultRetryConfig;
32
+ }
33
+ try {
34
+ const config = igniteClient.configuration.getObjectValue(IGNITE_RETRY_CONFIG_KEY, defaultRetryConfig);
35
+ return sanitizeRetryConfig(config);
36
+ }
37
+ catch (error) {
38
+ logger.error({ tag: 'authorization-service', error, key: IGNITE_RETRY_CONFIG_KEY, defaultValue: defaultRetryConfig }, 'Failed to get ignite retry config, using defaults');
39
+ return defaultRetryConfig;
40
+ }
41
+ }
42
+ function randomIntInclusive(min, max) {
43
+ if (max <= min) {
44
+ return min;
45
+ }
46
+ return Math.floor(min + Math.random() * (max - min + 1));
47
+ }
48
+ function buildHttpStatusMatchers(patterns) {
49
+ const matchers = [];
50
+ const addWildcardMatcher = (wildcard) => {
51
+ // Normalized 3-char pattern with digits or '*'
52
+ matchers.push((status) => {
53
+ const s = String(status);
54
+ if (s.length !== 3) {
55
+ return false;
56
+ }
57
+ for (let i = 0; i < 3; i++) {
58
+ const w = wildcard[i];
59
+ const c = s[i];
60
+ if (w === '*') {
61
+ continue;
62
+ }
63
+ if (w !== c) {
64
+ return false;
65
+ }
66
+ }
67
+ return true;
68
+ });
69
+ };
70
+ for (const raw of patterns ?? []) {
71
+ const p = String(raw).trim();
72
+ if (!p) {
73
+ continue;
74
+ }
75
+ // Exact numeric status (e.g. "429")
76
+ if (/^\d+$/.test(p)) {
77
+ const exact = Number(p);
78
+ if (Number.isFinite(exact)) {
79
+ matchers.push((status) => status === exact);
80
+ }
81
+ continue;
82
+ }
83
+ // Wildcards for 3-digit HTTP codes:
84
+ // - "5**" => 5xx
85
+ // - "5*9" => 5?9
86
+ if (/^[0-9*]+$/.test(p) && p.includes('*')) {
87
+ const normalized = p.length < 3 ? p.padEnd(3, '*') : p;
88
+ if (normalized.length !== 3) {
89
+ logger.warn({ tag: 'authorization-service', pattern: p }, 'Invalid retry status wildcard pattern (expected a 3-character pattern like "5**" or "5*9")');
90
+ }
91
+ else {
92
+ addWildcardMatcher(normalized);
93
+ }
94
+ continue;
95
+ }
96
+ logger.warn({ tag: 'authorization-service', pattern: p }, 'Invalid retry status pattern (supported: exact code like "429" or wildcard like "5**")');
97
+ }
98
+ return matchers;
99
+ }
100
+ function shouldRetryOnResponseStatus(responseOrStatus, statusMatchers) {
101
+ const status = responseOrStatus?.status;
102
+ if (typeof status !== 'number') {
103
+ return false;
104
+ }
105
+ return statusMatchers.some(matcher => matcher(status));
106
+ }
107
+ const onRetryCallback = (attempt, error, response, isTimeoutError) => {
108
+ const effectiveMaxRetries = getRetryConfig().retries;
109
+ if (attempt == effectiveMaxRetries) {
110
+ logger.error({ tag: 'authorization-service', attempt, error, response, isTimeoutError }, 'Authorization attempt failed');
15
111
  }
16
112
  else {
17
- logger.info({ tag: 'authorization-service', attempt, error }, 'Authorization attempt failed, trying again');
113
+ logger.info({ tag: 'authorization-service', attempt, error, response, isTimeoutError }, 'Authorization attempt failed, trying again');
18
114
  }
19
115
  };
20
116
  /**
21
117
  * Exponential backoff retry delay callback
22
- * Calculates delay as: baseDelay * 2^(attemptCount - 1)
118
+ * Calculates delay as: baseDelay * (exponentBase)^(attemptCount - 1) + jitter(min..max)
23
119
  * Example: attempt 1 -> 100ms, attempt 2 -> 200ms, attempt 3 -> 400ms
24
120
  */
25
121
  const calcDelayDurationInMs = ({ attemptCount }) => {
26
- return RETRY_DELAY_MS * Math.pow(2, attemptCount - 1);
122
+ const { baseDelayMs, exponentBase, jitterMinMs, jitterMaxMs } = getRetryConfig();
123
+ const jitterMin = Math.min(jitterMinMs, jitterMaxMs);
124
+ const jitterMax = Math.max(jitterMinMs, jitterMaxMs);
125
+ const expDelay = baseDelayMs * Math.pow(exponentBase, attemptCount - 1);
126
+ const jitter = randomIntInclusive(jitterMin, jitterMax);
127
+ return expDelay + jitter;
27
128
  };
28
- function logOnFetchFail(retriesLeft, error) {
29
- if (retriesLeft == 0) {
30
- logger.error({ retriesLeft, error }, `Authorization attempt failed due to ${error.message}`);
129
+ let mondayFetchOptions = {
130
+ retries: defaultRetryConfig.retries,
131
+ };
132
+ class AuthorizationInternalService {
133
+ static get igniteClient() {
134
+ return igniteClient;
31
135
  }
32
- else {
33
- logger.info({ retriesLeft, error }, `Authorization attempt failed due to ${error.message}, trying again`);
136
+ static set igniteClient(client) {
137
+ igniteClient = client;
34
138
  }
35
- }
36
- let mondayFetchOptions = defaultMondayFetchOptions;
37
- class AuthorizationInternalService {
38
- static igniteClient;
39
139
  static skipAuthorization(requset) {
40
140
  requset.authorizationSkipPerformed = true;
41
141
  }
@@ -63,16 +163,20 @@ class AuthorizationInternalService {
63
163
  return signAuthorizationHeader({ appName: INTERNAL_APP_NAME, accountId, userId });
64
164
  }
65
165
  static setRequestFetchOptions(customMondayFetchOptions) {
166
+ const sanitizedOptions = { ...customMondayFetchOptions };
167
+ if (sanitizedOptions.retries !== undefined) {
168
+ sanitizedOptions.retries = Math.max(0, Math.min(5, sanitizedOptions.retries));
169
+ }
66
170
  mondayFetchOptions = {
67
- ...defaultMondayFetchOptions,
68
- ...customMondayFetchOptions,
171
+ ...defaultRetryConfig,
172
+ ...sanitizedOptions,
69
173
  };
70
174
  }
71
175
  static getRequestFetchOptions() {
72
176
  return mondayFetchOptions;
73
177
  }
74
178
  static setIgniteClient(client) {
75
- this.igniteClient = client;
179
+ igniteClient = client;
76
180
  }
77
181
  static getRequestTimeout() {
78
182
  const isDevEnv = process.env.NODE_ENV === 'development';
@@ -96,14 +200,25 @@ class AuthorizationInternalService {
96
200
  }
97
201
  static getRetriesPolicy() {
98
202
  const fetchOptions = AuthorizationInternalService.getRequestFetchOptions();
99
- const retryDelayMS = calcDelayDurationInMs;
203
+ const retryConfig = getRetryConfig();
204
+ const statusMatchers = buildHttpStatusMatchers(retryConfig.retryOnStatusPatterns);
205
+ const defaultRetryOn = (_attempt, _error, response, isTimeoutError) => {
206
+ return isTimeoutError ? true : shouldRetryOnResponseStatus(response ?? undefined, statusMatchers);
207
+ };
208
+ // Sanitize retries from fetchOptions: clamp between 0 and 5
209
+ const rawMaxRetries = fetchOptions?.retries ?? retryConfig.retries;
210
+ const effectiveMaxRetries = Math.max(0, Math.min(5, rawMaxRetries));
211
+ const defaultGetTimeout = timeoutsCount => calcDelayDurationInMs({ attemptCount: timeoutsCount }) + AuthorizationInternalService.getRequestTimeout();
100
212
  return {
101
- useRetries: !!fetchOptions.retries,
102
- maxRetries: fetchOptions.retries ?? 0,
103
- onRetry: onRetryCallback,
104
- retryDelayMS,
213
+ useRetries: fetchOptions?.useRetries ?? true,
214
+ maxRetries: effectiveMaxRetries,
215
+ retryDelayMS: fetchOptions?.retryDelayMS ?? calcDelayDurationInMs,
216
+ onRetry: fetchOptions?.callback ?? onRetryCallback,
217
+ retryOn: fetchOptions?.retryOn ?? defaultRetryOn,
218
+ timeoutRetries: fetchOptions?.timeoutRetries ?? effectiveMaxRetries,
219
+ getTimeout: fetchOptions?.getTimeout ?? defaultGetTimeout,
105
220
  };
106
221
  }
107
222
  }
108
223
 
109
- export { AuthorizationInternalService, MAX_RETRIES, RETRY_DELAY_MS, calcDelayDurationInMs, logger, onRetryCallback };
224
+ export { AuthorizationInternalService, IGNITE_RETRY_CONFIG_KEY, MAX_RETRIES, RETRY_DELAY_MS, calcDelayDurationInMs, logger, onRetryCallback };
@@ -1,13 +1,13 @@
1
- import { MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
2
1
  import { IgniteClient } from '@mondaydotcomorg/ignite-sdk';
3
2
  import { Action, AuthorizationObject, AuthorizationParams, AuthorizationResource } from './types/general';
4
3
  import { ScopedAction, ScopedActionPermit, ScopedActionResponseObject, ScopeOptions } from './types/scoped-actions-contracts';
4
+ import { AuthorizationFetchOptions } from './types/fetch-options';
5
5
  export interface AuthorizeResponse {
6
6
  isAuthorized: boolean;
7
7
  unauthorizedIds?: number[];
8
8
  unauthorizedObjects?: AuthorizationObject[];
9
9
  }
10
- export declare function setRequestFetchOptions(customMondayFetchOptions: MondayFetchOptions): void;
10
+ export declare function setRequestFetchOptions(customMondayFetchOptions: AuthorizationFetchOptions): void;
11
11
  export declare class AuthorizationService {
12
12
  private static get graphApi();
13
13
  private static _graphApi?;
@@ -1 +1 @@
1
- {"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../../src/authorization-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG1G,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAY1C,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC7C;AAED,wBAAgB,sBAAsB,CAAC,wBAAwB,EAAE,kBAAkB,QAElF;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IACvD,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC;;;OAGG;WACU,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,qBAAqB,EAAE,EAClC,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;CAmF1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F;AAED,wBAAsB,eAAe,kBAMpC;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAiBjH"}
1
+ {"version":3,"file":"authorization-service.d.ts","sourceRoot":"","sources":["../../src/authorization-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG1G,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACb,MAAM,kCAAkC,CAAC;AAM1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAOlE,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,yBAAyB,QAEzF;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,KAAK,QAAQ,GAK1B;IACD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAW;IAEpC,OAAO,CAAC,MAAM,KAAK,WAAW,GAK7B;IACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAc;IAE1C,MAAM,CAAC,eAAe,IAAI,IAAI;IAK9B,MAAM,CAAC,WAAW,CAAC,MAAC;IACpB,MAAM,CAAC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IACvD,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC;;;OAGG;WACU,YAAY,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,qBAAqB,EAAE,EAClC,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;CAmF1C;AAED,wBAAgB,cAAc,CAC5B,MAAM,KAAA,EACN,sCAAsC,GAAE,MAAiD,QAY1F;AAED,wBAAsB,eAAe,kBAMpC;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAiBjH"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AACxC,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD,oBAAY,eAAe;IACzB,UAAU,mCAAmC;CAC9C;AAED,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAUjE,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AACxC,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD,oBAAY,eAAe;IACzB,UAAU,mCAAmC;CAC9C;AAED,eAAO,MAAM,cAAc;;sCAEA,MAAM,UAAU,MAAM,UAAU,MAAM;CAEvD,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAKjE,CAAC"}
@@ -9,11 +9,6 @@ const ERROR_MESSAGES = {
9
9
  REQUEST_FAILED: (method, status, reason) => `MondayAuthorization: [${method}] request failed with status ${status} with reason: ${reason}`,
10
10
  };
11
11
  const DEFAULT_FETCH_OPTIONS = {
12
- retryPolicy: {
13
- useRetries: true,
14
- maxRetries: 3,
15
- retryDelayMS: 10,
16
- },
17
12
  logPolicy: {
18
13
  logErrors: 'error',
19
14
  logRequests: 'info',
@@ -1,6 +1,6 @@
1
- import { MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
2
1
  import { MetricsClient } from './metrics-service';
3
2
  import * as TestKit from './testKit';
3
+ import { AuthorizationFetchOptions } from './types/fetch-options';
4
4
  interface MetricsInitOptions {
5
5
  client?: MetricsClient;
6
6
  serviceName?: string;
@@ -10,7 +10,7 @@ interface MetricsInitOptions {
10
10
  }
11
11
  export interface InitOptions {
12
12
  prometheus?: any;
13
- mondayFetchOptions?: MondayFetchOptions;
13
+ mondayFetchOptions?: AuthorizationFetchOptions;
14
14
  redisClient?: any;
15
15
  grantedFeatureRedisExpirationInSeconds?: number;
16
16
  metrics?: MetricsInitOptions;
@@ -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;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,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,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;AACrH,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,iCAAiC,EACjC,gCAAgC,EAChC,gCAAgC,EAChC,+BAA+B,EAC/B,8BAA8B,EAC9B,8BAA8B,EAC9B,2BAA2B,IAAI,mCAAmC,EAClE,yBAAyB,IAAI,iCAAiC,GAC/D,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,kCAAkC,IAAI,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAEhI,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,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,yBAAyB,CAAC;IAC/C,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,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,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;AACrH,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,iCAAiC,EACjC,gCAAgC,EAChC,gCAAgC,EAChC,+BAA+B,EAC/B,8BAA8B,EAC9B,8BAA8B,EAC9B,2BAA2B,IAAI,mCAAmC,EAClE,yBAAyB,IAAI,iCAAiC,GAC/D,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,kCAAkC,IAAI,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAEhI,OAAO,EAAE,OAAO,EAAE,CAAC"}