@ahoo-wang/fetcher-cosec 3.0.3 → 3.0.6

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/index.es.js CHANGED
@@ -1,16 +1,16 @@
1
- import { REQUEST_BODY_INTERCEPTOR_ORDER as D, FetcherError as S, ResultExtractors as U } from "@ahoo-wang/fetcher";
2
- import { nanoid as w } from "nanoid";
1
+ import { REQUEST_BODY_INTERCEPTOR_ORDER as w, FetcherError as D, ResultExtractors as y } from "@ahoo-wang/fetcher";
2
+ import { nanoid as U } from "nanoid";
3
3
  import { KeyStorage as f } from "@ahoo-wang/fetcher-storage";
4
4
  import { BroadcastTypedEventBus as O, SerialTypedEventBus as _ } from "@ahoo-wang/fetcher-eventbus";
5
5
  const a = class a {
6
6
  };
7
7
  a.DEVICE_ID = "CoSec-Device-Id", a.APP_ID = "CoSec-App-Id", a.AUTHORIZATION = "Authorization", a.REQUEST_ID = "CoSec-Request-Id";
8
8
  let n = a;
9
- const E = class E {
9
+ const u = class u {
10
10
  };
11
- E.UNAUTHORIZED = 401, E.FORBIDDEN = 403;
12
- let h = E;
13
- const j = {
11
+ u.UNAUTHORIZED = 401, u.FORBIDDEN = 403;
12
+ let h = u;
13
+ const ne = {
14
14
  ALLOW: { authorized: !0, reason: "Allow" },
15
15
  EXPLICIT_DENY: { authorized: !1, reason: "Explicit Deny" },
16
16
  IMPLICIT_DENY: { authorized: !1, reason: "Implicit Deny" },
@@ -24,17 +24,17 @@ class C {
24
24
  * @returns A unique request ID
25
25
  */
26
26
  generateId() {
27
- return w();
27
+ return U();
28
28
  }
29
29
  }
30
- const N = new C(), m = "CoSecRequestInterceptor", P = D + 1e3, A = "Ignore-Refresh-Token";
31
- class G {
30
+ const N = new C(), m = "CoSecRequestInterceptor", g = w + 1e3, k = "Ignore-Refresh-Token";
31
+ class b {
32
32
  /**
33
33
  * Creates a new CoSecRequestInterceptor instance.
34
34
  * @param options - The CoSec configuration options including appId, deviceIdStorage, and tokenManager
35
35
  */
36
36
  constructor(e) {
37
- this.name = m, this.order = P, this.options = e;
37
+ this.name = m, this.order = g, this.options = e;
38
38
  }
39
39
  /**
40
40
  * Intercept requests to add CoSec authentication headers.
@@ -59,19 +59,19 @@ class G {
59
59
  * It will attempt to refresh the token before adding the Authorization header to the request.
60
60
  */
61
61
  async intercept(e) {
62
- const t = N.generateId(), r = this.options.deviceIdStorage.getOrCreate(), o = e.ensureRequestHeaders();
63
- o[n.APP_ID] = this.options.appId, o[n.DEVICE_ID] = r, o[n.REQUEST_ID] = t;
62
+ const t = N.generateId(), s = this.options.deviceIdStorage.getOrCreate(), o = e.ensureRequestHeaders();
63
+ o[n.APP_ID] = this.options.appId, o[n.DEVICE_ID] = s, o[n.REQUEST_ID] = t;
64
64
  }
65
65
  }
66
- const b = "AuthorizationRequestInterceptor", z = P + 1e3;
67
- class V {
66
+ const M = "AuthorizationRequestInterceptor", z = g + 1e3;
67
+ class v {
68
68
  /**
69
69
  * Creates an AuthorizationRequestInterceptor instance.
70
70
  *
71
71
  * @param options - Configuration options containing the token manager
72
72
  */
73
73
  constructor(e) {
74
- this.options = e, this.name = b, this.order = z;
74
+ this.options = e, this.name = M, this.order = z;
75
75
  }
76
76
  /**
77
77
  * Intercepts the request exchange to add authorization headers.
@@ -86,18 +86,18 @@ class V {
86
86
  */
87
87
  async intercept(e) {
88
88
  let t = this.options.tokenManager.currentToken;
89
- const r = e.ensureRequestHeaders();
90
- !t || r[n.AUTHORIZATION] || (!e.attributes.has(A) && t.isRefreshNeeded && t.isRefreshable && await this.options.tokenManager.refresh(), t = this.options.tokenManager.currentToken, t && (r[n.AUTHORIZATION] = `Bearer ${t.access.token}`));
89
+ const s = e.ensureRequestHeaders();
90
+ !t || s[n.AUTHORIZATION] || (!e.attributes.has(k) && t.isRefreshNeeded && t.isRefreshable && await this.options.tokenManager.refresh(), t = this.options.tokenManager.currentToken, t && (s[n.AUTHORIZATION] = `Bearer ${t.access.token}`));
91
91
  }
92
92
  }
93
- const M = "AuthorizationResponseInterceptor", q = Number.MIN_SAFE_INTEGER + 1e3;
94
- class X {
93
+ const q = "AuthorizationResponseInterceptor", F = Number.MIN_SAFE_INTEGER + 1e3;
94
+ class B {
95
95
  /**
96
96
  * Creates a new AuthorizationResponseInterceptor instance.
97
97
  * @param options - The CoSec configuration options including token storage and refresher
98
98
  */
99
99
  constructor(e) {
100
- this.options = e, this.name = M, this.order = q;
100
+ this.options = e, this.name = q, this.order = F;
101
101
  }
102
102
  /**
103
103
  * Intercepts the response and handles unauthorized responses by refreshing tokens.
@@ -108,16 +108,16 @@ class X {
108
108
  if (t && t.status === h.UNAUTHORIZED && this.options.tokenManager.isRefreshable)
109
109
  try {
110
110
  await this.options.tokenManager.refresh(), await e.fetcher.interceptors.exchange(e);
111
- } catch (r) {
112
- throw this.options.tokenManager.tokenStorage.remove(), r;
111
+ } catch (s) {
112
+ throw this.options.tokenManager.tokenStorage.remove(), s;
113
113
  }
114
114
  }
115
115
  }
116
- const d = "cosec-device-id";
117
- class W extends f {
116
+ const T = "cosec-device-id";
117
+ class K extends f {
118
118
  constructor(e = {
119
- key: d,
120
- eventBus: new O({ delegate: new _(d) })
119
+ key: T,
120
+ eventBus: new O({ delegate: new _(T) })
121
121
  }) {
122
122
  super(e);
123
123
  }
@@ -139,99 +139,74 @@ class W extends f {
139
139
  return e || (e = this.generateDeviceId(), this.set(e)), e;
140
140
  }
141
141
  }
142
- function k(s) {
143
- try {
144
- if (typeof s != "string")
145
- return null;
146
- const e = s.split(".");
147
- if (e.length !== 3)
148
- return null;
149
- const r = e[1].replace(/-/g, "+").replace(/_/g, "/"), o = r.padEnd(
150
- r.length + (4 - r.length % 4) % 4,
151
- "="
152
- ), c = decodeURIComponent(
153
- atob(o).split("").map(function(i) {
154
- return "%" + ("00" + i.charCodeAt(0).toString(16)).slice(-2);
155
- }).join("")
156
- );
157
- return JSON.parse(c);
158
- } catch (e) {
159
- return console.error("Failed to parse JWT token", e), null;
160
- }
161
- }
162
- function v(s, e = 0) {
163
- const t = typeof s == "string" ? k(s) : s;
164
- if (!t)
165
- return !0;
166
- const r = t.exp;
167
- return r ? Date.now() / 1e3 > r - e : !1;
168
- }
169
- class p {
170
- /**
171
- * Creates a new JwtToken instance
172
- */
173
- constructor(e, t = 0) {
174
- this.token = e, this.earlyPeriod = t, this.payload = k(e);
175
- }
176
- /**
177
- * Checks if the token is expired
178
- * @returns true if the token is expired, false otherwise
179
- */
180
- get isExpired() {
181
- return this.payload ? v(this.payload, this.earlyPeriod) : !0;
182
- }
183
- }
184
- class g {
185
- /**
186
- * Creates a new JwtCompositeToken instance
187
- */
188
- constructor(e, t = 0) {
189
- this.token = e, this.earlyPeriod = t, this.access = new p(e.accessToken, t), this.refresh = new p(e.refreshToken, t);
190
- }
191
- /**
192
- * Checks if the access token needs to be refreshed
193
- * @returns true if the access token is expired, false otherwise
194
- */
195
- get isRefreshNeeded() {
196
- return this.access.isExpired;
197
- }
198
- /**
199
- * Checks if the refresh token is still valid and can be used to refresh the access token
200
- * @returns true if the refresh token is not expired, false otherwise
201
- */
202
- get isRefreshable() {
203
- return !this.refresh.isExpired;
204
- }
205
- }
206
- class y {
207
- constructor(e = 0) {
208
- this.earlyPeriod = e;
209
- }
142
+ const H = "ForbiddenErrorInterceptor", Z = 0;
143
+ class J {
210
144
  /**
211
- * Deserializes a JSON string to a JwtCompositeToken
212
- * @param value The JSON string representation of a composite token
213
- * @returns A JwtCompositeToken instance
145
+ * Creates a new ForbiddenErrorInterceptor instance.
146
+ *
147
+ * @param options - Configuration options containing the callback to handle forbidden responses.
148
+ * Must include the `onForbidden` callback function.
149
+ *
150
+ * @throws Will throw an error if options are not provided or if `onForbidden` callback is missing.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * const interceptor = new ForbiddenErrorInterceptor({
155
+ * onForbidden: async (exchange) => {
156
+ * // Handle forbidden access
157
+ * }
158
+ * });
159
+ * ```
214
160
  */
215
- deserialize(e) {
216
- const t = JSON.parse(e);
217
- return new g(t, this.earlyPeriod);
161
+ constructor(e) {
162
+ this.options = e, this.name = H, this.order = Z;
218
163
  }
219
164
  /**
220
- * Serializes a JwtCompositeToken to a JSON string
221
- * @param value The JwtCompositeToken to serialize
222
- * @returns A JSON string representation of the composite token
165
+ * Intercepts fetch exchanges to detect and handle forbidden (403) responses.
166
+ *
167
+ * This method examines the response status code and invokes the configured `onForbidden`
168
+ * callback when a 403 Forbidden response is detected. The method is asynchronous to
169
+ * allow the callback to perform async operations like API calls, redirects, or UI updates.
170
+ *
171
+ * The interceptor only acts on responses with status code 403. Other error codes are
172
+ * ignored and passed through to other error interceptors in the chain.
173
+ *
174
+ * @param exchange - The fetch exchange containing request, response, and error information
175
+ * to be inspected for forbidden status codes. The exchange object provides
176
+ * access to the original request, response details, and any error information.
177
+ * @returns Promise that resolves when the forbidden error handling is complete.
178
+ * Returns void - the method does not modify the exchange or return values.
179
+ *
180
+ * @remarks
181
+ * - Only responds to HTTP 403 status codes
182
+ * - Does not retry requests or modify responses
183
+ * - Allows async operations in the callback
184
+ * - Does not throw exceptions - delegates all error handling to the callback
185
+ * - Safe to use with other error interceptors
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * // The intercept method is called automatically by the fetcher
190
+ * // No manual invocation needed - this is for documentation purposes
191
+ * const interceptor = new ForbiddenErrorInterceptor({
192
+ * onForbidden: async (exchange) => {
193
+ * // exchange.response.status === 403
194
+ * // exchange.request contains original request details
195
+ * await handleForbiddenAccess(exchange);
196
+ * }
197
+ * });
198
+ * ```
223
199
  */
224
- serialize(e) {
225
- return JSON.stringify(e.token);
200
+ async intercept(e) {
201
+ e.response?.status === h.FORBIDDEN && await this.options.onForbidden(e);
226
202
  }
227
203
  }
228
- const $ = new y();
229
- class u extends S {
204
+ class E extends D {
230
205
  constructor(e, t) {
231
- super("Refresh token failed.", t), this.token = e, this.name = "RefreshTokenError", Object.setPrototypeOf(this, u.prototype);
206
+ super("Refresh token failed.", t), this.token = e, this.name = "RefreshTokenError", Object.setPrototypeOf(this, E.prototype);
232
207
  }
233
208
  }
234
- class ee {
209
+ class Q {
235
210
  /**
236
211
  * Creates a new JwtTokenManager instance
237
212
  * @param tokenStorage The storage used to persist tokens
@@ -259,7 +234,7 @@ class ee {
259
234
  return this.refreshInProgress ? this.refreshInProgress : (this.refreshInProgress = this.tokenRefresher.refresh(e.token).then((t) => {
260
235
  this.tokenStorage.setCompositeToken(t);
261
236
  }).catch((t) => {
262
- throw this.tokenStorage.remove(), new u(e, t);
237
+ throw this.tokenStorage.remove(), new E(e, t);
263
238
  }).finally(() => {
264
239
  this.refreshInProgress = void 0;
265
240
  }), this.refreshInProgress);
@@ -279,18 +254,18 @@ class ee {
279
254
  return this.currentToken ? this.currentToken.isRefreshable : !1;
280
255
  }
281
256
  }
282
- const B = "ResourceAttributionRequestInterceptor", F = Number.MAX_SAFE_INTEGER;
283
- class te {
257
+ const x = "tenantId", Y = "ownerId", L = "ResourceAttributionRequestInterceptor", j = Number.MAX_SAFE_INTEGER;
258
+ class G {
284
259
  /**
285
260
  * Creates a new ResourceAttributionRequestInterceptor
286
261
  * @param options - Configuration options for resource attribution including tenantId, ownerId and tokenStorage
287
262
  */
288
263
  constructor({
289
- tenantId: e = "tenantId",
290
- ownerId: t = "ownerId",
291
- tokenStorage: r
264
+ tenantId: e = x,
265
+ ownerId: t = Y,
266
+ tokenStorage: s
292
267
  }) {
293
- this.name = B, this.order = F, this.tenantIdPathKey = e, this.ownerIdPathKey = t, this.tokenStorage = r;
268
+ this.name = L, this.order = j, this.tenantIdPathKey = e, this.ownerIdPathKey = t, this.tokenStorage = s;
294
269
  }
295
270
  /**
296
271
  * Intercepts outgoing requests and automatically adds tenant and owner ID path parameters
@@ -301,69 +276,127 @@ class te {
301
276
  const t = this.tokenStorage.get();
302
277
  if (!t)
303
278
  return;
304
- const r = t.access.payload;
305
- if (!r || !r.tenantId && !r.sub)
279
+ const s = t.access.payload;
280
+ if (!s || !s.tenantId && !s.sub)
306
281
  return;
307
282
  const o = e.fetcher.urlBuilder.urlTemplateResolver.extractPathParams(
308
283
  e.request.url
309
- ), c = this.tenantIdPathKey, i = e.ensureRequestUrlParams().path, I = r.tenantId;
310
- I && o.includes(c) && !i[c] && (i[c] = I);
311
- const R = this.ownerIdPathKey, T = r.sub;
312
- T && o.includes(R) && !i[R] && (i[R] = T);
284
+ ), c = this.tenantIdPathKey, i = e.ensureRequestUrlParams().path, d = s.tenantId;
285
+ d && o.includes(c) && !i[c] && (i[c] = d);
286
+ const R = this.ownerIdPathKey, I = s.sub;
287
+ I && o.includes(R) && !i[R] && (i[R] = I);
288
+ }
289
+ }
290
+ function S(r) {
291
+ try {
292
+ if (typeof r != "string")
293
+ return null;
294
+ const e = r.split(".");
295
+ if (e.length !== 3)
296
+ return null;
297
+ const s = e[1].replace(/-/g, "+").replace(/_/g, "/"), o = s.padEnd(
298
+ s.length + (4 - s.length % 4) % 4,
299
+ "="
300
+ ), c = decodeURIComponent(
301
+ atob(o).split("").map(function(i) {
302
+ return "%" + ("00" + i.charCodeAt(0).toString(16)).slice(-2);
303
+ }).join("")
304
+ );
305
+ return JSON.parse(c);
306
+ } catch (e) {
307
+ return console.error("Failed to parse JWT token", e), null;
313
308
  }
314
309
  }
315
- class re {
310
+ function V(r, e = 0) {
311
+ const t = typeof r == "string" ? S(r) : r;
312
+ if (!t)
313
+ return !0;
314
+ const s = t.exp;
315
+ return s ? Date.now() / 1e3 > s - e : !1;
316
+ }
317
+ class p {
316
318
  /**
317
- * Creates a new instance of CoSecTokenRefresher.
318
- *
319
- * @param options The configuration options for the token refresher including fetcher and endpoint
319
+ * Creates a new JwtToken instance
320
320
  */
321
- constructor(e) {
322
- this.options = e;
321
+ constructor(e, t = 0) {
322
+ this.token = e, this.earlyPeriod = t, this.payload = S(e);
323
323
  }
324
324
  /**
325
- * Refresh the given token and return a new CompositeToken.
326
- *
327
- * @param token The token to refresh
328
- * @returns A Promise that resolves to a new CompositeToken
325
+ * Checks if the token is expired
326
+ * @returns true if the token is expired, false otherwise
329
327
  */
330
- refresh(e) {
331
- return this.options.fetcher.post(
332
- this.options.endpoint,
333
- {
334
- body: e
335
- },
336
- {
337
- resultExtractor: U.Json,
338
- attributes: /* @__PURE__ */ new Map([[A, !0]])
339
- }
340
- );
328
+ get isExpired() {
329
+ return this.payload ? V(this.payload, this.earlyPeriod) : !0;
330
+ }
331
+ }
332
+ class A {
333
+ /**
334
+ * Creates a new JwtCompositeToken instance
335
+ */
336
+ constructor(e, t = 0) {
337
+ this.token = e, this.earlyPeriod = t, this.access = new p(e.accessToken, t), this.refresh = new p(e.refreshToken, t);
338
+ }
339
+ /**
340
+ * Checks if the access token needs to be refreshed
341
+ * @returns true if the access token is expired, false otherwise
342
+ */
343
+ get isRefreshNeeded() {
344
+ return this.access.isExpired;
345
+ }
346
+ /**
347
+ * Checks if the refresh token is still valid and can be used to refresh the access token
348
+ * @returns true if the refresh token is not expired, false otherwise
349
+ */
350
+ get isRefreshable() {
351
+ return !this.refresh.isExpired;
352
+ }
353
+ }
354
+ class P {
355
+ constructor(e = 0) {
356
+ this.earlyPeriod = e;
357
+ }
358
+ /**
359
+ * Deserializes a JSON string to a JwtCompositeToken
360
+ * @param value The JSON string representation of a composite token
361
+ * @returns A JwtCompositeToken instance
362
+ */
363
+ deserialize(e) {
364
+ const t = JSON.parse(e);
365
+ return new A(t, this.earlyPeriod);
366
+ }
367
+ /**
368
+ * Serializes a JwtCompositeToken to a JSON string
369
+ * @param value The JwtCompositeToken to serialize
370
+ * @returns A JSON string representation of the composite token
371
+ */
372
+ serialize(e) {
373
+ return JSON.stringify(e.token);
341
374
  }
342
375
  }
343
- const l = "cosec-token";
344
- class se extends f {
376
+ const ie = new P(), l = "cosec-token";
377
+ class W extends f {
345
378
  constructor(e = {
346
379
  key: l,
347
380
  eventBus: new O({ delegate: new _(l) })
348
381
  }) {
349
382
  super({
350
- serializer: new y(e.earlyPeriod),
383
+ serializer: new P(e.earlyPeriod),
351
384
  ...e
352
385
  }), this.earlyPeriod = e.earlyPeriod ?? 0;
353
386
  }
354
387
  setCompositeToken(e) {
355
- this.set(new g(e, this.earlyPeriod));
388
+ this.set(new A(e, this.earlyPeriod));
356
389
  }
357
390
  }
358
- const K = "UnauthorizedErrorInterceptor", H = 0;
359
- class oe {
391
+ const X = "UnauthorizedErrorInterceptor", $ = 0;
392
+ class ee {
360
393
  /**
361
394
  * Creates a new UnauthorizedErrorInterceptor instance.
362
395
  *
363
396
  * @param options - Configuration options containing the callback to handle unauthorized responses
364
397
  */
365
398
  constructor(e) {
366
- this.options = e, this.name = K, this.order = H;
399
+ this.options = e, this.name = X, this.order = $;
367
400
  }
368
401
  /**
369
402
  * Intercepts fetch exchanges to detect and handle unauthorized (401) responses
@@ -389,108 +422,169 @@ class oe {
389
422
  * ```
390
423
  */
391
424
  async intercept(e) {
392
- (e.response?.status === h.UNAUTHORIZED || e.error instanceof u) && await this.options.onUnauthorized(e);
425
+ (e.response?.status === h.UNAUTHORIZED || e.error instanceof E) && await this.options.onUnauthorized(e);
393
426
  }
394
427
  }
395
- const Z = "ForbiddenErrorInterceptor", J = 0;
396
- class ne {
428
+ class ae {
397
429
  /**
398
- * Creates a new ForbiddenErrorInterceptor instance.
430
+ * Creates a new CoSecConfigurer instance with the provided configuration.
399
431
  *
400
- * @param options - Configuration options containing the callback to handle forbidden responses.
401
- * Must include the `onForbidden` callback function.
432
+ * This constructor conditionally creates dependencies based on the configuration:
433
+ * - TokenStorage and DeviceIdStorage are always created (using defaults if not provided)
434
+ * - JwtTokenManager is only created if tokenRefresher is provided
402
435
  *
403
- * @throws Will throw an error if options are not provided or if `onForbidden` callback is missing.
436
+ * @param config - CoSec configuration object
404
437
  *
405
438
  * @example
406
439
  * ```typescript
407
- * const interceptor = new ForbiddenErrorInterceptor({
408
- * onForbidden: async (exchange) => {
409
- * // Handle forbidden access
410
- * }
440
+ * // Full setup with all dependencies
441
+ * const configurer = new CoSecConfigurer({
442
+ * appId: 'my-app',
443
+ * tokenRefresher: myTokenRefresher,
444
+ * });
445
+ *
446
+ * // Minimal setup with custom storage
447
+ * const configurer = new CoSecConfigurer({
448
+ * appId: 'my-app',
449
+ * tokenStorage: customStorage,
450
+ * deviceIdStorage: customDeviceStorage,
411
451
  * });
412
452
  * ```
413
453
  */
414
454
  constructor(e) {
415
- this.options = e, this.name = Z, this.order = J;
455
+ this.config = e, this.tokenStorage = e.tokenStorage ?? new W(), this.deviceIdStorage = e.deviceIdStorage ?? new K(), e.tokenRefresher && (this.tokenManager = new Q(
456
+ this.tokenStorage,
457
+ e.tokenRefresher
458
+ ));
416
459
  }
417
460
  /**
418
- * Intercepts fetch exchanges to detect and handle forbidden (403) responses.
461
+ * Applies CoSec interceptors to the provided Fetcher instance.
419
462
  *
420
- * This method examines the response status code and invokes the configured `onForbidden`
421
- * callback when a 403 Forbidden response is detected. The method is asynchronous to
422
- * allow the callback to perform async operations like API calls, redirects, or UI updates.
463
+ * This method conditionally configures interceptors based on the provided configuration:
423
464
  *
424
- * The interceptor only acts on responses with status code 403. Other error codes are
425
- * ignored and passed through to other error interceptors in the chain.
465
+ * Always added:
466
+ * 1. CoSecRequestInterceptor - Adds CoSec headers (appId, deviceId, requestId)
467
+ * 2. ResourceAttributionRequestInterceptor - Adds tenant/owner path parameters
426
468
  *
427
- * @param exchange - The fetch exchange containing request, response, and error information
428
- * to be inspected for forbidden status codes. The exchange object provides
429
- * access to the original request, response details, and any error information.
430
- * @returns Promise that resolves when the forbidden error handling is complete.
431
- * Returns void - the method does not modify the exchange or return values.
469
+ * Only when `tokenRefresher` is provided:
470
+ * 3. AuthorizationRequestInterceptor - Adds Bearer token authentication
471
+ * 4. AuthorizationResponseInterceptor - Handles token refresh on 401 responses
432
472
  *
433
- * @remarks
434
- * - Only responds to HTTP 403 status codes
435
- * - Does not retry requests or modify responses
436
- * - Allows async operations in the callback
437
- * - Does not throw exceptions - delegates all error handling to the callback
438
- * - Safe to use with other error interceptors
473
+ * Only when corresponding handlers are provided:
474
+ * 5. UnauthorizedErrorInterceptor - Handles 401 unauthorized errors
475
+ * 6. ForbiddenErrorInterceptor - Handles 403 forbidden errors
476
+ *
477
+ * @param fetcher - The Fetcher instance to configure
439
478
  *
440
479
  * @example
441
480
  * ```typescript
442
- * // The intercept method is called automatically by the fetcher
443
- * // No manual invocation needed - this is for documentation purposes
444
- * const interceptor = new ForbiddenErrorInterceptor({
445
- * onForbidden: async (exchange) => {
446
- * // exchange.response.status === 403
447
- * // exchange.request contains original request details
448
- * await handleForbiddenAccess(exchange);
449
- * }
481
+ * const fetcher = new Fetcher({ baseURL: '/api' });
482
+ * const configurer = new CoSecConfigurer({
483
+ * appId: 'my-app',
484
+ * tokenRefresher: myTokenRefresher,
485
+ * onUnauthorized: handle401,
486
+ * onForbidden: handle403,
450
487
  * });
488
+ *
489
+ * configurer.applyTo(fetcher);
490
+ * // Now fetcher has all CoSec interceptors configured
451
491
  * ```
452
492
  */
453
- async intercept(e) {
454
- e.response?.status === h.FORBIDDEN && await this.options.onForbidden(e);
493
+ applyTo(e) {
494
+ e.interceptors.request.use(
495
+ new b({
496
+ appId: this.config.appId,
497
+ deviceIdStorage: this.deviceIdStorage
498
+ })
499
+ ), e.interceptors.request.use(
500
+ new G({
501
+ tokenStorage: this.tokenStorage
502
+ })
503
+ ), this.tokenManager && (e.interceptors.request.use(
504
+ new v({
505
+ tokenManager: this.tokenManager
506
+ })
507
+ ), e.interceptors.response.use(
508
+ new B({
509
+ tokenManager: this.tokenManager
510
+ })
511
+ )), this.config.onUnauthorized && e.interceptors.error.use(
512
+ new ee({
513
+ onUnauthorized: this.config.onUnauthorized
514
+ })
515
+ ), this.config.onForbidden && e.interceptors.error.use(
516
+ new J({
517
+ onForbidden: this.config.onForbidden
518
+ })
519
+ );
520
+ }
521
+ }
522
+ class ce {
523
+ /**
524
+ * Creates a new instance of CoSecTokenRefresher.
525
+ *
526
+ * @param options The configuration options for the token refresher including fetcher and endpoint
527
+ */
528
+ constructor(e) {
529
+ this.options = e;
530
+ }
531
+ /**
532
+ * Refresh the given token and return a new CompositeToken.
533
+ *
534
+ * @param token The token to refresh
535
+ * @returns A Promise that resolves to a new CompositeToken
536
+ */
537
+ refresh(e) {
538
+ return this.options.fetcher.post(
539
+ this.options.endpoint,
540
+ {
541
+ body: e
542
+ },
543
+ {
544
+ resultExtractor: y.Json,
545
+ attributes: /* @__PURE__ */ new Map([[k, !0]])
546
+ }
547
+ );
455
548
  }
456
549
  }
457
550
  export {
458
- b as AUTHORIZATION_REQUEST_INTERCEPTOR_NAME,
551
+ M as AUTHORIZATION_REQUEST_INTERCEPTOR_NAME,
459
552
  z as AUTHORIZATION_REQUEST_INTERCEPTOR_ORDER,
460
- M as AUTHORIZATION_RESPONSE_INTERCEPTOR_NAME,
461
- q as AUTHORIZATION_RESPONSE_INTERCEPTOR_ORDER,
462
- V as AuthorizationRequestInterceptor,
463
- X as AuthorizationResponseInterceptor,
464
- j as AuthorizeResults,
553
+ q as AUTHORIZATION_RESPONSE_INTERCEPTOR_NAME,
554
+ F as AUTHORIZATION_RESPONSE_INTERCEPTOR_ORDER,
555
+ v as AuthorizationRequestInterceptor,
556
+ B as AuthorizationResponseInterceptor,
557
+ ne as AuthorizeResults,
465
558
  m as COSEC_REQUEST_INTERCEPTOR_NAME,
466
- P as COSEC_REQUEST_INTERCEPTOR_ORDER,
559
+ g as COSEC_REQUEST_INTERCEPTOR_ORDER,
560
+ ae as CoSecConfigurer,
467
561
  n as CoSecHeaders,
468
- G as CoSecRequestInterceptor,
469
- re as CoSecTokenRefresher,
470
- d as DEFAULT_COSEC_DEVICE_ID_KEY,
562
+ b as CoSecRequestInterceptor,
563
+ ce as CoSecTokenRefresher,
564
+ T as DEFAULT_COSEC_DEVICE_ID_KEY,
471
565
  l as DEFAULT_COSEC_TOKEN_KEY,
472
- W as DeviceIdStorage,
473
- Z as FORBIDDEN_ERROR_INTERCEPTOR_NAME,
474
- J as FORBIDDEN_ERROR_INTERCEPTOR_ORDER,
475
- ne as ForbiddenErrorInterceptor,
476
- A as IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY,
477
- g as JwtCompositeToken,
478
- y as JwtCompositeTokenSerializer,
566
+ K as DeviceIdStorage,
567
+ H as FORBIDDEN_ERROR_INTERCEPTOR_NAME,
568
+ Z as FORBIDDEN_ERROR_INTERCEPTOR_ORDER,
569
+ J as ForbiddenErrorInterceptor,
570
+ k as IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY,
571
+ A as JwtCompositeToken,
572
+ P as JwtCompositeTokenSerializer,
479
573
  p as JwtToken,
480
- ee as JwtTokenManager,
574
+ Q as JwtTokenManager,
481
575
  C as NanoIdGenerator,
482
- B as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_NAME,
483
- F as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_ORDER,
484
- u as RefreshTokenError,
485
- te as ResourceAttributionRequestInterceptor,
576
+ L as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_NAME,
577
+ j as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_ORDER,
578
+ E as RefreshTokenError,
579
+ G as ResourceAttributionRequestInterceptor,
486
580
  h as ResponseCodes,
487
- se as TokenStorage,
488
- K as UNAUTHORIZED_ERROR_INTERCEPTOR_NAME,
489
- H as UNAUTHORIZED_ERROR_INTERCEPTOR_ORDER,
490
- oe as UnauthorizedErrorInterceptor,
581
+ W as TokenStorage,
582
+ X as UNAUTHORIZED_ERROR_INTERCEPTOR_NAME,
583
+ $ as UNAUTHORIZED_ERROR_INTERCEPTOR_ORDER,
584
+ ee as UnauthorizedErrorInterceptor,
491
585
  N as idGenerator,
492
- v as isTokenExpired,
493
- $ as jwtCompositeTokenSerializer,
494
- k as parseJwtPayload
586
+ V as isTokenExpired,
587
+ ie as jwtCompositeTokenSerializer,
588
+ S as parseJwtPayload
495
589
  };
496
590
  //# sourceMappingURL=index.es.js.map