@ahoo-wang/fetcher-cosec 3.5.0 → 3.5.2

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,11 +1,11 @@
1
1
  import { REQUEST_BODY_INTERCEPTOR_ORDER as w, FetcherError as D, ResultExtractors as U } from "@ahoo-wang/fetcher";
2
2
  import { nanoid as y } from "nanoid";
3
3
  import { KeyStorage as f, typedIdentitySerializer as C } from "@ahoo-wang/fetcher-storage";
4
- import { BroadcastTypedEventBus as O, SerialTypedEventBus as _ } from "@ahoo-wang/fetcher-eventbus";
4
+ import { BroadcastTypedEventBus as O, SerialTypedEventBus as g } 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
- let n = a;
8
+ let o = a;
9
9
  const u = class u {
10
10
  };
11
11
  u.UNAUTHORIZED = 401, u.FORBIDDEN = 403;
@@ -27,14 +27,14 @@ class m {
27
27
  return y();
28
28
  }
29
29
  }
30
- const N = new m(), b = "CoSecRequestInterceptor", g = w + 1e3, k = "Ignore-Refresh-Token";
30
+ const _ = new m(), b = "CoSecRequestInterceptor", N = w + 1e3, k = "Ignore-Refresh-Token";
31
31
  class M {
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 = b, this.order = g, this.options = e;
37
+ this.name = b, this.order = N, this.options = e;
38
38
  }
39
39
  /**
40
40
  * Intercept requests to add CoSec authentication headers.
@@ -59,11 +59,11 @@ class M {
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 = _.generateId(), r = this.options.deviceIdStorage.getOrCreate(), n = e.ensureRequestHeaders();
63
+ n[o.APP_ID] = this.options.appId, n[o.DEVICE_ID] = r, n[o.REQUEST_ID] = t;
64
64
  }
65
65
  }
66
- const z = "AuthorizationRequestInterceptor", q = g + 1e3;
66
+ const z = "AuthorizationRequestInterceptor", q = N + 1e3;
67
67
  class v {
68
68
  /**
69
69
  * Creates an AuthorizationRequestInterceptor instance.
@@ -87,7 +87,7 @@ class v {
87
87
  async intercept(e) {
88
88
  let t = this.options.tokenManager.currentToken;
89
89
  const r = e.ensureRequestHeaders();
90
- !t || r[n.AUTHORIZATION] || (!e.attributes.has(k) && t.isRefreshNeeded && t.isRefreshable && await this.options.tokenManager.refresh(), t = this.options.tokenManager.currentToken, t && (r[n.AUTHORIZATION] = `Bearer ${t.access.token}`));
90
+ !t || r[o.AUTHORIZATION] || (!e.attributes.has(k) && t.isRefreshNeeded && t.isRefreshable && await this.options.tokenManager.refresh(), t = this.options.tokenManager.currentToken, t && (r[o.AUTHORIZATION] = `Bearer ${t.access.token}`));
91
91
  }
92
92
  }
93
93
  const F = "AuthorizationResponseInterceptor", K = Number.MIN_SAFE_INTEGER + 1e3;
@@ -118,7 +118,7 @@ class H extends f {
118
118
  constructor({
119
119
  key: e = p,
120
120
  eventBus: t = new O({
121
- delegate: new _(p)
121
+ delegate: new g(p)
122
122
  }),
123
123
  ...r
124
124
  } = {}) {
@@ -130,7 +130,7 @@ class H extends f {
130
130
  * @returns A newly generated device ID
131
131
  */
132
132
  generateDeviceId() {
133
- return N.generateId();
133
+ return _.generateId();
134
134
  }
135
135
  /**
136
136
  * Get or create a device ID.
@@ -142,8 +142,8 @@ class H extends f {
142
142
  return e || (e = this.generateDeviceId(), this.set(e)), e;
143
143
  }
144
144
  }
145
- const Z = "ForbiddenErrorInterceptor", J = 0;
146
- class Q {
145
+ const Z = "ForbiddenErrorInterceptor", x = 0;
146
+ class J {
147
147
  /**
148
148
  * Creates a new ForbiddenErrorInterceptor instance.
149
149
  *
@@ -162,7 +162,7 @@ class Q {
162
162
  * ```
163
163
  */
164
164
  constructor(e) {
165
- this.options = e, this.name = Z, this.order = J;
165
+ this.options = e, this.name = Z, this.order = x;
166
166
  }
167
167
  /**
168
168
  * Intercepts fetch exchanges to detect and handle forbidden (403) responses.
@@ -209,7 +209,7 @@ class E extends D {
209
209
  super("Refresh token failed.", t), this.token = e, this.name = "RefreshTokenError", Object.setPrototypeOf(this, E.prototype);
210
210
  }
211
211
  }
212
- class x {
212
+ class Q {
213
213
  /**
214
214
  * Creates a new JwtTokenManager instance
215
215
  * @param tokenStorage The storage used to persist tokens
@@ -282,12 +282,12 @@ class V {
282
282
  const r = t.access.payload;
283
283
  if (!r || !r.tenantId && !r.sub)
284
284
  return;
285
- const o = e.fetcher.urlBuilder.urlTemplateResolver.extractPathParams(
285
+ const n = e.fetcher.urlBuilder.urlTemplateResolver.extractPathParams(
286
286
  e.request.url
287
- ), c = this.tenantIdPathKey, i = e.ensureRequestUrlParams().path, d = r.tenantId;
288
- d && o.includes(c) && !i[c] && (i[c] = d);
289
- const R = this.ownerIdPathKey, I = r.sub;
290
- I && o.includes(R) && !i[R] && (i[R] = I);
287
+ ), c = this.tenantIdPathKey, i = e.ensureRequestUrlParams().path, R = r.tenantId;
288
+ R && n.includes(c) && !i[c] && (i[c] = R);
289
+ const d = this.ownerIdPathKey, I = r.sub;
290
+ I && n.includes(d) && !i[d] && (i[d] = I);
291
291
  }
292
292
  }
293
293
  function S(s) {
@@ -297,11 +297,11 @@ function S(s) {
297
297
  const e = s.split(".");
298
298
  if (e.length !== 3)
299
299
  return null;
300
- const r = e[1].replace(/-/g, "+").replace(/_/g, "/"), o = r.padEnd(
300
+ const r = e[1].replace(/-/g, "+").replace(/_/g, "/"), n = r.padEnd(
301
301
  r.length + (4 - r.length % 4) % 4,
302
302
  "="
303
303
  ), c = decodeURIComponent(
304
- atob(o).split("").map(function(i) {
304
+ atob(n).split("").map(function(i) {
305
305
  return "%" + ("00" + i.charCodeAt(0).toString(16)).slice(-2);
306
306
  }).join("")
307
307
  );
@@ -319,14 +319,27 @@ function W(s, e = 0) {
319
319
  }
320
320
  class T {
321
321
  /**
322
- * Creates a new JwtToken instance
322
+ * Creates a new JwtToken instance.
323
+ *
324
+ * Parses the JWT token string to extract the payload and stores the early period
325
+ * for expiration checks.
326
+ *
327
+ * @param token The raw JWT token string to parse
328
+ * @param earlyPeriod The early expiration period in milliseconds (default: 0).
329
+ * Tokens are considered expired this many milliseconds before their actual expiration time.
330
+ *
331
+ * @throws Will not throw but payload will be null if token parsing fails
323
332
  */
324
333
  constructor(e, t = 0) {
325
334
  this.token = e, this.earlyPeriod = t, this.payload = S(e);
326
335
  }
327
336
  /**
328
- * Checks if the token is expired
329
- * @returns true if the token is expired, false otherwise
337
+ * Checks if the token is expired.
338
+ *
339
+ * Considers both the token's expiration time and the early period.
340
+ * Returns true if the payload is null (parsing failed) or if the token is expired.
341
+ *
342
+ * @returns true if the token is expired or invalid, false otherwise
330
343
  */
331
344
  get isExpired() {
332
345
  return this.payload ? W(this.payload, this.earlyPeriod) : !0;
@@ -334,41 +347,69 @@ class T {
334
347
  }
335
348
  class A {
336
349
  /**
337
- * Creates a new JwtCompositeToken instance
350
+ * Creates a new JwtCompositeToken instance.
351
+ *
352
+ * Initializes both access and refresh token instances with the provided early period.
353
+ *
354
+ * @param token The composite token containing access and refresh token strings
355
+ * @param earlyPeriod The early expiration period in milliseconds (default: 0)
338
356
  */
339
357
  constructor(e, t = 0) {
340
358
  this.token = e, this.earlyPeriod = t, this.access = new T(e.accessToken, t), this.refresh = new T(e.refreshToken, t);
341
359
  }
342
360
  /**
343
- * Checks if the access token needs to be refreshed
361
+ * Checks if the access token needs to be refreshed.
362
+ *
344
363
  * @returns true if the access token is expired, false otherwise
345
364
  */
346
365
  get isRefreshNeeded() {
347
366
  return this.access.isExpired;
348
367
  }
349
368
  /**
350
- * Checks if the refresh token is still valid and can be used to refresh the access token
369
+ * Checks if the refresh token is still valid and can be used to refresh the access token.
370
+ *
351
371
  * @returns true if the refresh token is not expired, false otherwise
352
372
  */
353
373
  get isRefreshable() {
354
374
  return !this.refresh.isExpired;
355
375
  }
376
+ /**
377
+ * Checks if the user is currently authenticated (access token is valid).
378
+ *
379
+ * @returns true if the access token is not expired, false otherwise
380
+ */
381
+ get authenticated() {
382
+ return !this.access.isExpired;
383
+ }
356
384
  }
357
385
  class P {
386
+ /**
387
+ * Creates a new JwtCompositeTokenSerializer instance.
388
+ *
389
+ * @param earlyPeriod The early expiration period in milliseconds to use for deserialized tokens (default: 0)
390
+ */
358
391
  constructor(e = 0) {
359
392
  this.earlyPeriod = e;
360
393
  }
361
394
  /**
362
- * Deserializes a JSON string to a JwtCompositeToken
395
+ * Deserializes a JSON string to a JwtCompositeToken.
396
+ *
397
+ * Parses the JSON string and creates a new JwtCompositeToken instance with the stored tokens.
398
+ *
363
399
  * @param value The JSON string representation of a composite token
364
400
  * @returns A JwtCompositeToken instance
401
+ * @throws SyntaxError if the JSON string is invalid
402
+ * @throws Error if the parsed object doesn't match the expected CompositeToken structure
365
403
  */
366
404
  deserialize(e) {
367
405
  const t = JSON.parse(e);
368
406
  return new A(t, this.earlyPeriod);
369
407
  }
370
408
  /**
371
- * Serializes a JwtCompositeToken to a JSON string
409
+ * Serializes a JwtCompositeToken to a JSON string.
410
+ *
411
+ * Converts the composite token to a JSON string for storage.
412
+ *
372
413
  * @param value The JwtCompositeToken to serialize
373
414
  * @returns A JSON string representation of the composite token
374
415
  */
@@ -378,24 +419,66 @@ class P {
378
419
  }
379
420
  const ae = new P(), l = "cosec-token";
380
421
  class X extends f {
422
+ /**
423
+ * Creates a new TokenStorage instance.
424
+ * @param options - Configuration options for the token storage.
425
+ * @param options.key - The storage key for tokens. Defaults to DEFAULT_COSEC_TOKEN_KEY.
426
+ * @param options.eventBus - Event bus for token change notifications. Defaults to a BroadcastTypedEventBus with SerialTypedEventBus delegate.
427
+ * @param options.earlyPeriod - Early period for token refresh in milliseconds. Defaults to 0.
428
+ * @param reset - Additional options passed to KeyStorage.
429
+ */
381
430
  constructor({
382
431
  key: e = l,
383
432
  eventBus: t = new O({
384
- delegate: new _(l)
433
+ delegate: new g(l)
385
434
  }),
386
435
  earlyPeriod: r = 0,
387
- ...o
436
+ ...n
388
437
  } = {}) {
389
438
  super({
390
439
  key: e,
391
440
  eventBus: t,
392
- ...o,
441
+ ...n,
393
442
  serializer: new P(r)
394
443
  }), this.earlyPeriod = r;
395
444
  }
445
+ /**
446
+ * Sets a composite token in storage.
447
+ * Converts the composite token to a JwtCompositeToken and stores it.
448
+ * @deprecated Use signIn() instead for better semantic clarity.
449
+ * @param compositeToken - The composite token containing access and refresh tokens.
450
+ */
396
451
  setCompositeToken(e) {
452
+ this.signIn(e);
453
+ }
454
+ /**
455
+ * Signs in by storing the composite token.
456
+ * @param compositeToken - The composite token to store for authentication.
457
+ */
458
+ signIn(e) {
397
459
  this.set(new A(e, this.earlyPeriod));
398
460
  }
461
+ /**
462
+ * Signs out by removing the stored token.
463
+ * Clears the token from storage.
464
+ */
465
+ signOut() {
466
+ this.remove();
467
+ }
468
+ /**
469
+ * Checks if the user is authenticated.
470
+ * @returns true if a valid token is present and authenticated, false otherwise.
471
+ */
472
+ get authenticated() {
473
+ return this.get()?.authenticated === !0;
474
+ }
475
+ /**
476
+ * Gets the current user's JWT payload.
477
+ * @returns The JWT payload of the current user if authenticated, null otherwise.
478
+ */
479
+ get currentUser() {
480
+ return this.authenticated ? this.get()?.access.payload ?? null : null;
481
+ }
399
482
  }
400
483
  const $ = "UnauthorizedErrorInterceptor", ee = 0;
401
484
  class te {
@@ -461,7 +544,7 @@ class ce {
461
544
  * ```
462
545
  */
463
546
  constructor(e) {
464
- this.config = e, this.tokenStorage = e.tokenStorage ?? new X(), this.deviceIdStorage = e.deviceIdStorage ?? new H(), e.tokenRefresher && (this.tokenManager = new x(
547
+ this.config = e, this.tokenStorage = e.tokenStorage ?? new X(), this.deviceIdStorage = e.deviceIdStorage ?? new H(), e.tokenRefresher && (this.tokenManager = new Q(
465
548
  this.tokenStorage,
466
549
  e.tokenRefresher
467
550
  ));
@@ -522,7 +605,7 @@ class ce {
522
605
  onUnauthorized: this.config.onUnauthorized
523
606
  })
524
607
  ), this.config.onForbidden && e.interceptors.error.use(
525
- new Q({
608
+ new J({
526
609
  onForbidden: this.config.onForbidden
527
610
  })
528
611
  );
@@ -602,22 +685,22 @@ export {
602
685
  B as AuthorizationResponseInterceptor,
603
686
  ie as AuthorizeResults,
604
687
  b as COSEC_REQUEST_INTERCEPTOR_NAME,
605
- g as COSEC_REQUEST_INTERCEPTOR_ORDER,
688
+ N as COSEC_REQUEST_INTERCEPTOR_ORDER,
606
689
  ce as CoSecConfigurer,
607
- n as CoSecHeaders,
690
+ o as CoSecHeaders,
608
691
  M as CoSecRequestInterceptor,
609
692
  he as CoSecTokenRefresher,
610
693
  p as DEFAULT_COSEC_DEVICE_ID_KEY,
611
694
  l as DEFAULT_COSEC_TOKEN_KEY,
612
695
  H as DeviceIdStorage,
613
696
  Z as FORBIDDEN_ERROR_INTERCEPTOR_NAME,
614
- J as FORBIDDEN_ERROR_INTERCEPTOR_ORDER,
615
- Q as ForbiddenErrorInterceptor,
697
+ x as FORBIDDEN_ERROR_INTERCEPTOR_ORDER,
698
+ J as ForbiddenErrorInterceptor,
616
699
  k as IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY,
617
700
  A as JwtCompositeToken,
618
701
  P as JwtCompositeTokenSerializer,
619
702
  T as JwtToken,
620
- x as JwtTokenManager,
703
+ Q as JwtTokenManager,
621
704
  m as NanoIdGenerator,
622
705
  j as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_NAME,
623
706
  G as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_ORDER,
@@ -628,7 +711,7 @@ export {
628
711
  $ as UNAUTHORIZED_ERROR_INTERCEPTOR_NAME,
629
712
  ee as UNAUTHORIZED_ERROR_INTERCEPTOR_ORDER,
630
713
  te as UnauthorizedErrorInterceptor,
631
- N as idGenerator,
714
+ _ as idGenerator,
632
715
  W as isTokenExpired,
633
716
  ae as jwtCompositeTokenSerializer,
634
717
  S as parseJwtPayload