@ahoo-wang/fetcher-cosec 1.6.3 → 1.6.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.
@@ -1,4 +1,4 @@
1
- import { KeyStorage } from './storage';
1
+ import { KeyStorage } from '@ahoo-wang/fetcher-storage';
2
2
  export declare const DEFAULT_COSEC_DEVICE_ID_KEY = "cosec-device-id";
3
3
  /**
4
4
  * Storage class for managing device identifiers.
@@ -1 +1 @@
1
- {"version":3,"file":"deviceIdStorage.d.ts","sourceRoot":"","sources":["../src/deviceIdStorage.ts"],"names":[],"mappings":"AAcA,OAAO,EAA2B,UAAU,EAAE,MAAM,WAAW,CAAC;AAGhE,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAE7D;;GAEG;AACH,qBAAa,eAAgB,SAAQ,UAAU,CAAC,MAAM,CAAC;gBACzC,GAAG,GAAE,MAAoC;IAQrD;;;;OAIG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;;;OAIG;IACH,WAAW,IAAI,MAAM;CAYtB"}
1
+ {"version":3,"file":"deviceIdStorage.d.ts","sourceRoot":"","sources":["../src/deviceIdStorage.ts"],"names":[],"mappings":"AAcA,OAAO,EAA+C,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAErG,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAE7D;;GAEG;AACH,qBAAa,eAAgB,SAAQ,UAAU,CAAC,MAAM,CAAC;gBACzC,GAAG,GAAE,MAAoC;IAQrD;;;;OAIG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;;;OAIG;IACH,WAAW,IAAI,MAAM;CAYtB"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export * from './storage';
2
1
  export * from './cosecRequestInterceptor';
3
2
  export * from './cosecResponseInterceptor';
4
3
  export * from './deviceIdStorage';
@@ -6,9 +5,7 @@ export * from './idGenerator';
6
5
  export * from './jwts';
7
6
  export * from './jwtToken';
8
7
  export * from './jwtTokenManager';
9
- export * from './serializer';
10
8
  export * from './tokenRefresher';
11
9
  export * from './tokenStorage';
12
10
  export * from './types';
13
- export * from './env';
14
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,WAAW,CAAC;AAC1B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC"}
package/dist/index.es.js CHANGED
@@ -1,9 +1,96 @@
1
- import { REQUEST_BODY_INTERCEPTOR_ORDER as k, ResultExtractors as y } from "@ahoo-wang/fetcher";
2
- import { nanoid as m } from "nanoid";
3
- function E() {
1
+ import { REQUEST_BODY_INTERCEPTOR_ORDER as m, ResultExtractors as y } from "@ahoo-wang/fetcher";
2
+ import { nanoid as S } from "nanoid";
3
+ const a = class a {
4
+ };
5
+ a.DEVICE_ID = "CoSec-Device-Id", a.APP_ID = "CoSec-App-Id", a.AUTHORIZATION = "Authorization", a.REQUEST_ID = "CoSec-Request-Id";
6
+ let i = a;
7
+ const l = class l {
8
+ };
9
+ l.UNAUTHORIZED = 401;
10
+ let h = l;
11
+ const x = {
12
+ ALLOW: { authorized: !0, reason: "Allow" },
13
+ EXPLICIT_DENY: { authorized: !1, reason: "Explicit Deny" },
14
+ IMPLICIT_DENY: { authorized: !1, reason: "Implicit Deny" },
15
+ TOKEN_EXPIRED: { authorized: !1, reason: "Token Expired" },
16
+ TOO_MANY_REQUESTS: { authorized: !1, reason: "Too Many Requests" }
17
+ };
18
+ class C {
19
+ /**
20
+ * Generate a unique request ID.
21
+ *
22
+ * @returns A unique request ID
23
+ */
24
+ generateId() {
25
+ return S();
26
+ }
27
+ }
28
+ const E = new C(), O = "CoSecRequestInterceptor", _ = m + 1e3, g = "Ignore-Refresh-Token";
29
+ class J {
30
+ /**
31
+ * Creates a new CoSecRequestInterceptor instance.
32
+ * @param options - The CoSec configuration options including appId, deviceIdStorage, and tokenManager
33
+ */
34
+ constructor(e) {
35
+ this.name = O, this.order = _, this.options = e;
36
+ }
37
+ /**
38
+ * Intercept requests to add CoSec authentication headers.
39
+ *
40
+ * This method adds the following headers to each request:
41
+ * - CoSec-App-Id: The application identifier from the CoSec options
42
+ * - CoSec-Device-Id: A unique device identifier, either retrieved from storage or generated
43
+ * - CoSec-Request-Id: A unique identifier for this specific request
44
+ * - Authorization: Bearer token if available in token storage
45
+ *
46
+ * @param exchange - The fetch exchange containing the request to process
47
+ *
48
+ * @remarks
49
+ * This method runs after RequestBodyInterceptor but before FetchInterceptor.
50
+ * It ensures that authentication headers are added to the request after all
51
+ * body processing is complete. The positioning allows for proper authentication
52
+ * header addition after all request body transformations are finished, ensuring
53
+ * that the final request is properly authenticated before being sent over the network.
54
+ * This execution order prevents authentication headers from being overwritten by
55
+ * subsequent request processing interceptors.
56
+ *
57
+ * The method also handles token refreshing when the current token is expired but still refreshable.
58
+ * It will attempt to refresh the token before adding the Authorization header to the request.
59
+ */
60
+ async intercept(e) {
61
+ const t = E.generateId(), s = this.options.deviceIdStorage.getOrCreate(), o = e.ensureRequestHeaders();
62
+ o[i.APP_ID] = this.options.appId, o[i.DEVICE_ID] = s, o[i.REQUEST_ID] = t;
63
+ let n = this.options.tokenManager.currentToken;
64
+ !n || o[i.AUTHORIZATION] || (!e.attributes.has(g) && n.isRefreshNeeded && n.isRefreshable && await this.options.tokenManager.refresh(), n = this.options.tokenManager.currentToken, n && (o[i.AUTHORIZATION] = `Bearer ${n.access.token}`));
65
+ }
66
+ }
67
+ const N = "CoSecResponseInterceptor", D = Number.MIN_SAFE_INTEGER + 1e3;
68
+ class q {
69
+ /**
70
+ * Creates a new CoSecResponseInterceptor instance.
71
+ * @param options - The CoSec configuration options including token storage and refresher
72
+ */
73
+ constructor(e) {
74
+ this.name = N, this.order = D, this.options = e;
75
+ }
76
+ /**
77
+ * Intercepts the response and handles unauthorized responses by refreshing tokens.
78
+ * @param exchange - The fetch exchange containing request and response information
79
+ */
80
+ async intercept(e) {
81
+ const t = e.response;
82
+ if (t && t.status === h.UNAUTHORIZED && this.options.tokenManager.isRefreshable)
83
+ try {
84
+ await this.options.tokenManager.refresh(), await e.fetcher.interceptors.exchange(e);
85
+ } catch (s) {
86
+ throw this.options.tokenManager.tokenStorage.remove(), s;
87
+ }
88
+ }
89
+ }
90
+ function f() {
4
91
  return typeof window < "u";
5
92
  }
6
- class O {
93
+ class A {
7
94
  constructor() {
8
95
  this.store = /* @__PURE__ */ new Map(), this.listeners = /* @__PURE__ */ new Set();
9
96
  }
@@ -70,7 +157,7 @@ class O {
70
157
  * @param eventInit - The initialization object for the StorageEvent
71
158
  */
72
159
  notifyListeners(e) {
73
- E() && window.location && (e.url = e.url || window.location.href), e.storageArea = this, this.listeners.forEach((t) => {
160
+ f() && window.location && (e.url = e.url || window.location.href), e.storageArea = this, this.listeners.forEach((t) => {
74
161
  try {
75
162
  t(e);
76
163
  } catch (s) {
@@ -79,7 +166,7 @@ class O {
79
166
  });
80
167
  }
81
168
  }
82
- class _ {
169
+ class P {
83
170
  /**
84
171
  * Creates a new BrowserListenableStorage instance.
85
172
  * @param storage - The native Storage object to wrap (e.g., localStorage or sessionStorage)
@@ -142,37 +229,8 @@ class _ {
142
229
  this.storage.setItem(e, t);
143
230
  }
144
231
  }
145
- const u = "storage", h = () => E() ? new _(window.localStorage) : new O();
146
- class N {
147
- /**
148
- * Serializes a value to a JSON string
149
- * @param value The value to serialize
150
- * @returns The JSON string representation of the value
151
- */
152
- /**
153
- * Serializes a value to a JSON string
154
- * @param value The value to serialize
155
- * @returns The JSON string representation of the value
156
- */
157
- serialize(e) {
158
- return JSON.stringify(e);
159
- }
160
- /**
161
- * Deserializes a JSON string to a value
162
- * @template V The type of the deserialized value
163
- * @param value The JSON string to deserialize
164
- * @returns The deserialized value
165
- */
166
- /**
167
- * Deserializes a JSON string to a value
168
- * @param value The JSON string to deserialize
169
- * @returns The deserialized value
170
- */
171
- deserialize(e) {
172
- return JSON.parse(e);
173
- }
174
- }
175
- class g {
232
+ const u = "storage", c = () => f() ? new P(window.localStorage) : new A();
233
+ class I {
176
234
  /**
177
235
  * Returns the value as-is without serialization
178
236
  * @param value The value to pass through
@@ -201,19 +259,19 @@ class g {
201
259
  return e;
202
260
  }
203
261
  }
204
- const x = new N(), C = new g();
205
- function z() {
206
- return C;
262
+ const z = new I();
263
+ function v() {
264
+ return z;
207
265
  }
208
- class f {
266
+ class p {
209
267
  /**
210
268
  * Creates a new KeyStorage instance
211
269
  * @param options Configuration options for the storage
212
270
  */
213
271
  constructor(e) {
214
- this.cacheValue = null, this.listener = (t) => {
215
- t.key === this.key && (this.cacheValue = null, t.newValue && this.refreshCache(t.newValue));
216
- }, this.key = e.key, this.serializer = e.serializer ?? z(), this.storage = e.storage ?? h(), this.storage.addListener(this.listener);
272
+ this.cacheValue = null, this.refreshCacheListener = (t) => {
273
+ this.cacheValue = null, t.newValue && this.refreshCache(t.newValue);
274
+ }, this.key = e.key, this.serializer = e.serializer ?? v(), this.storage = e.storage ?? c(), this.addListener(this.refreshCacheListener);
217
275
  }
218
276
  /**
219
277
  * Refreshes the cached value by deserializing the provided string
@@ -222,6 +280,12 @@ class f {
222
280
  refreshCache(e) {
223
281
  this.cacheValue = this.serializer.deserialize(e);
224
282
  }
283
+ addListener(e) {
284
+ const t = (s) => {
285
+ s.key === this.key && e(s);
286
+ };
287
+ return this.storage.addListener(t);
288
+ }
225
289
  /**
226
290
  * Gets the value associated with the key from storage
227
291
  * Uses cached value if available, otherwise retrieves from storage and caches it
@@ -250,100 +314,13 @@ class f {
250
314
  this.storage.removeItem(this.key), this.cacheValue = null;
251
315
  }
252
316
  }
253
- const a = class a {
254
- };
255
- a.DEVICE_ID = "CoSec-Device-Id", a.APP_ID = "CoSec-App-Id", a.AUTHORIZATION = "Authorization", a.REQUEST_ID = "CoSec-Request-Id";
256
- let n = a;
257
- const l = class l {
258
- };
259
- l.UNAUTHORIZED = 401;
260
- let c = l;
261
- const Y = {
262
- ALLOW: { authorized: !0, reason: "Allow" },
263
- EXPLICIT_DENY: { authorized: !1, reason: "Explicit Deny" },
264
- IMPLICIT_DENY: { authorized: !1, reason: "Implicit Deny" },
265
- TOKEN_EXPIRED: { authorized: !1, reason: "Token Expired" },
266
- TOO_MANY_REQUESTS: { authorized: !1, reason: "Too Many Requests" }
267
- };
268
- class A {
269
- /**
270
- * Generate a unique request ID.
271
- *
272
- * @returns A unique request ID
273
- */
274
- generateId() {
275
- return m();
276
- }
277
- }
278
- const I = new A(), D = "CoSecRequestInterceptor", P = k + 1e3, p = "Ignore-Refresh-Token";
279
- class q {
280
- /**
281
- * Creates a new CoSecRequestInterceptor instance.
282
- * @param options - The CoSec configuration options including appId, deviceIdStorage, and tokenManager
283
- */
284
- constructor(e) {
285
- this.name = D, this.order = P, this.options = e;
286
- }
287
- /**
288
- * Intercept requests to add CoSec authentication headers.
289
- *
290
- * This method adds the following headers to each request:
291
- * - CoSec-App-Id: The application identifier from the CoSec options
292
- * - CoSec-Device-Id: A unique device identifier, either retrieved from storage or generated
293
- * - CoSec-Request-Id: A unique identifier for this specific request
294
- * - Authorization: Bearer token if available in token storage
295
- *
296
- * @param exchange - The fetch exchange containing the request to process
297
- *
298
- * @remarks
299
- * This method runs after RequestBodyInterceptor but before FetchInterceptor.
300
- * It ensures that authentication headers are added to the request after all
301
- * body processing is complete. The positioning allows for proper authentication
302
- * header addition after all request body transformations are finished, ensuring
303
- * that the final request is properly authenticated before being sent over the network.
304
- * This execution order prevents authentication headers from being overwritten by
305
- * subsequent request processing interceptors.
306
- *
307
- * The method also handles token refreshing when the current token is expired but still refreshable.
308
- * It will attempt to refresh the token before adding the Authorization header to the request.
309
- */
310
- async intercept(e) {
311
- const t = I.generateId(), s = this.options.deviceIdStorage.getOrCreate(), i = e.ensureRequestHeaders();
312
- i[n.APP_ID] = this.options.appId, i[n.DEVICE_ID] = s, i[n.REQUEST_ID] = t;
313
- let o = this.options.tokenManager.currentToken;
314
- !o || i[n.AUTHORIZATION] || (!e.attributes.has(p) && o.isRefreshNeeded && o.isRefreshable && await this.options.tokenManager.refresh(), o = this.options.tokenManager.currentToken, o && (i[n.AUTHORIZATION] = `Bearer ${o.access.token}`));
315
- }
316
- }
317
- const U = "CoSecResponseInterceptor", V = Number.MIN_SAFE_INTEGER + 1e3;
318
- class K {
319
- /**
320
- * Creates a new CoSecResponseInterceptor instance.
321
- * @param options - The CoSec configuration options including token storage and refresher
322
- */
323
- constructor(e) {
324
- this.name = U, this.order = V, this.options = e;
325
- }
326
- /**
327
- * Intercepts the response and handles unauthorized responses by refreshing tokens.
328
- * @param exchange - The fetch exchange containing request and response information
329
- */
330
- async intercept(e) {
331
- const t = e.response;
332
- if (t && t.status === c.UNAUTHORIZED && this.options.tokenManager.isRefreshable)
333
- try {
334
- await this.options.tokenManager.refresh(), await e.fetcher.interceptors.exchange(e);
335
- } catch (s) {
336
- throw this.options.tokenManager.tokenStorage.remove(), s;
337
- }
338
- }
339
- }
340
- const L = "cosec-device-id";
341
- class B extends f {
342
- constructor(e = L) {
317
+ const U = "cosec-device-id";
318
+ class Y extends p {
319
+ constructor(e = U) {
343
320
  super({
344
321
  key: e,
345
- serializer: new g(),
346
- storage: h()
322
+ serializer: new I(),
323
+ storage: c()
347
324
  });
348
325
  }
349
326
  /**
@@ -352,7 +329,7 @@ class B extends f {
352
329
  * @returns A newly generated device ID
353
330
  */
354
331
  generateDeviceId() {
355
- return I.generateId();
332
+ return E.generateId();
356
333
  }
357
334
  /**
358
335
  * Get or create a device ID.
@@ -369,20 +346,20 @@ function T(r) {
369
346
  const e = r.split(".");
370
347
  if (e.length !== 3)
371
348
  return null;
372
- const s = e[1].replace(/-/g, "+").replace(/_/g, "/"), i = s.padEnd(
349
+ const s = e[1].replace(/-/g, "+").replace(/_/g, "/"), o = s.padEnd(
373
350
  s.length + (4 - s.length % 4) % 4,
374
351
  "="
375
- ), o = decodeURIComponent(
376
- atob(i).split("").map(function(S) {
377
- return "%" + ("00" + S.charCodeAt(0).toString(16)).slice(-2);
352
+ ), n = decodeURIComponent(
353
+ atob(o).split("").map(function(w) {
354
+ return "%" + ("00" + w.charCodeAt(0).toString(16)).slice(-2);
378
355
  }).join("")
379
356
  );
380
- return JSON.parse(o);
357
+ return JSON.parse(n);
381
358
  } catch (e) {
382
359
  return console.error("Failed to parse JWT token", e), null;
383
360
  }
384
361
  }
385
- function b(r, e = 0) {
362
+ function L(r, e = 0) {
386
363
  const t = typeof r == "string" ? T(r) : r;
387
364
  if (!t)
388
365
  return !0;
@@ -401,7 +378,7 @@ class d {
401
378
  * @returns true if the token is expired, false otherwise
402
379
  */
403
380
  get isExpired() {
404
- return b(this.payload, this.earlyPeriod);
381
+ return L(this.payload, this.earlyPeriod);
405
382
  }
406
383
  }
407
384
  class R {
@@ -426,7 +403,7 @@ class R {
426
403
  return !this.refresh.isExpired;
427
404
  }
428
405
  }
429
- class w {
406
+ class k {
430
407
  constructor(e = 0) {
431
408
  this.earlyPeriod = e;
432
409
  }
@@ -448,8 +425,8 @@ class w {
448
425
  return JSON.stringify(e.token);
449
426
  }
450
427
  }
451
- const Q = new w();
452
- class j {
428
+ const K = new k();
429
+ class Q {
453
430
  /**
454
431
  * Creates a new JwtTokenManager instance
455
432
  * @param tokenStorage The storage used to persist tokens
@@ -524,18 +501,18 @@ class F {
524
501
  },
525
502
  {
526
503
  resultExtractor: y.Json,
527
- attributes: /* @__PURE__ */ new Map([[p, !0]])
504
+ attributes: /* @__PURE__ */ new Map([[g, !0]])
528
505
  }
529
506
  );
530
507
  }
531
508
  }
532
- const M = "cosec-token";
533
- class G extends f {
534
- constructor(e = M, t = 0) {
509
+ const V = "cosec-token";
510
+ class Z extends p {
511
+ constructor(e = V, t = 0) {
535
512
  super({
536
513
  key: e,
537
- storage: h(),
538
- serializer: new w(t)
514
+ storage: c(),
515
+ serializer: new k(t)
539
516
  }), this.earlyPeriod = t;
540
517
  }
541
518
  setCompositeToken(e) {
@@ -545,40 +522,29 @@ class G extends f {
545
522
  }
546
523
  }
547
524
  export {
548
- Y as AuthorizeResults,
549
- _ as BrowserListenableStorage,
550
- D as COSEC_REQUEST_INTERCEPTOR_NAME,
551
- P as COSEC_REQUEST_INTERCEPTOR_ORDER,
552
- U as COSEC_RESPONSE_INTERCEPTOR_NAME,
553
- V as COSEC_RESPONSE_INTERCEPTOR_ORDER,
554
- n as CoSecHeaders,
555
- q as CoSecRequestInterceptor,
556
- K as CoSecResponseInterceptor,
525
+ x as AuthorizeResults,
526
+ O as COSEC_REQUEST_INTERCEPTOR_NAME,
527
+ _ as COSEC_REQUEST_INTERCEPTOR_ORDER,
528
+ N as COSEC_RESPONSE_INTERCEPTOR_NAME,
529
+ D as COSEC_RESPONSE_INTERCEPTOR_ORDER,
530
+ i as CoSecHeaders,
531
+ J as CoSecRequestInterceptor,
532
+ q as CoSecResponseInterceptor,
557
533
  F as CoSecTokenRefresher,
558
- L as DEFAULT_COSEC_DEVICE_ID_KEY,
559
- M as DEFAULT_COSEC_TOKEN_KEY,
560
- B as DeviceIdStorage,
561
- p as IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY,
562
- g as IdentitySerializer,
563
- O as InMemoryListenableStorage,
564
- N as JsonSerializer,
534
+ U as DEFAULT_COSEC_DEVICE_ID_KEY,
535
+ V as DEFAULT_COSEC_TOKEN_KEY,
536
+ Y as DeviceIdStorage,
537
+ g as IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY,
565
538
  R as JwtCompositeToken,
566
- w as JwtCompositeTokenSerializer,
539
+ k as JwtCompositeTokenSerializer,
567
540
  d as JwtToken,
568
- j as JwtTokenManager,
569
- f as KeyStorage,
570
- A as NanoIdGenerator,
571
- c as ResponseCodes,
572
- u as STORAGE_EVENT_TYPE,
573
- G as TokenStorage,
574
- h as createListenableStorage,
575
- I as idGenerator,
576
- C as identitySerializer,
577
- E as isBrowser,
578
- b as isTokenExpired,
579
- x as jsonSerializer,
580
- Q as jwtCompositeTokenSerializer,
581
- T as parseJwtPayload,
582
- z as typedIdentitySerializer
541
+ Q as JwtTokenManager,
542
+ C as NanoIdGenerator,
543
+ h as ResponseCodes,
544
+ Z as TokenStorage,
545
+ E as idGenerator,
546
+ L as isTokenExpired,
547
+ K as jwtCompositeTokenSerializer,
548
+ T as parseJwtPayload
583
549
  };
584
550
  //# sourceMappingURL=index.es.js.map