@ahoo-wang/fetcher-cosec 0.8.9 → 0.9.1
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/cosecRequestInterceptor.d.ts +5 -6
- package/dist/cosecRequestInterceptor.d.ts.map +1 -1
- package/dist/cosecResponseInterceptor.d.ts +3 -6
- package/dist/cosecResponseInterceptor.d.ts.map +1 -1
- package/dist/deviceIdStorage.d.ts +14 -6
- package/dist/deviceIdStorage.d.ts.map +1 -1
- package/dist/idGenerator.d.ts +5 -3
- package/dist/idGenerator.d.ts.map +1 -1
- package/dist/inMemoryStorage.d.ts +1 -1
- package/dist/index.es.js +46 -35
- package/dist/index.umd.js +1 -1
- package/dist/tokenRefresher.d.ts +10 -7
- package/dist/tokenRefresher.d.ts.map +1 -1
- package/dist/tokenStorage.d.ts +8 -4
- package/dist/tokenStorage.d.ts.map +1 -1
- package/dist/types.d.ts +10 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FetchExchange, Interceptor } from '@ahoo-wang/fetcher';
|
|
2
2
|
import { CoSecOptions } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* CoSec
|
|
4
|
+
* Interceptor that automatically adds CoSec authentication headers to requests.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* This interceptor adds the following headers to each request:
|
|
7
7
|
* - CoSec-Device-Id: Device identifier (stored in localStorage or generated)
|
|
8
8
|
* - CoSec-App-Id: Application identifier
|
|
9
9
|
* - Authorization: Bearer token
|
|
@@ -21,7 +21,7 @@ export declare class CoSecRequestInterceptor implements Interceptor {
|
|
|
21
21
|
private options;
|
|
22
22
|
constructor(options: CoSecOptions);
|
|
23
23
|
/**
|
|
24
|
-
* Intercept requests to add CoSec authentication headers
|
|
24
|
+
* Intercept requests to add CoSec authentication headers.
|
|
25
25
|
*
|
|
26
26
|
* This method adds the following headers to each request:
|
|
27
27
|
* - CoSec-App-Id: The application identifier from the CoSec options
|
|
@@ -29,9 +29,8 @@ export declare class CoSecRequestInterceptor implements Interceptor {
|
|
|
29
29
|
* - CoSec-Request-Id: A unique identifier for this specific request
|
|
30
30
|
* - Authorization: Bearer token if available in token storage
|
|
31
31
|
*
|
|
32
|
-
* @param exchange - The fetch exchange containing the request to
|
|
33
|
-
* @returns The modified exchange with CoSec authentication headers added
|
|
32
|
+
* @param exchange - The fetch exchange containing the request to process
|
|
34
33
|
*/
|
|
35
|
-
intercept(exchange: FetchExchange):
|
|
34
|
+
intercept(exchange: FetchExchange): void;
|
|
36
35
|
}
|
|
37
36
|
//# sourceMappingURL=cosecRequestInterceptor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosecRequestInterceptor.d.ts","sourceRoot":"","sources":["../src/cosecRequestInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAgB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAgB,YAAY,EAAE,MAAM,SAAS,CAAC;AAGrD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAwB,YAAW,WAAW;IACzD,IAAI,SAA6B;IACjC,KAAK,SAAkC;IACvC,OAAO,CAAC,OAAO,CAAe;gBAElB,OAAO,EAAE,YAAY;IAIjC
|
|
1
|
+
{"version":3,"file":"cosecRequestInterceptor.d.ts","sourceRoot":"","sources":["../src/cosecRequestInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAgB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAgB,YAAY,EAAE,MAAM,SAAS,CAAC;AAGrD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAwB,YAAW,WAAW;IACzD,IAAI,SAA6B;IACjC,KAAK,SAAkC;IACvC,OAAO,CAAC,OAAO,CAAe;gBAElB,OAAO,EAAE,YAAY;IAIjC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa;CAuBlC"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { CoSecOptions } from './types';
|
|
2
2
|
import { FetchExchange, Interceptor } from '@ahoo-wang/fetcher';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Handles automatic token refresh based on response codes
|
|
4
|
+
* Interceptor that handles automatic token refresh based on response codes.
|
|
7
5
|
*
|
|
8
6
|
* @remarks
|
|
9
7
|
* This interceptor runs near the end of the response processing chain, just before
|
|
@@ -18,7 +16,7 @@ export declare class CoSecResponseInterceptor implements Interceptor {
|
|
|
18
16
|
private options;
|
|
19
17
|
constructor(options: CoSecOptions);
|
|
20
18
|
/**
|
|
21
|
-
* Intercept responses to handle token refresh for unauthorized responses
|
|
19
|
+
* Intercept responses to handle token refresh for unauthorized responses.
|
|
22
20
|
*
|
|
23
21
|
* This method checks if a response has a 401 (UNAUTHORIZED) status code and attempts
|
|
24
22
|
* to refresh the authentication token if one is available. If token refresh is successful,
|
|
@@ -26,9 +24,8 @@ export declare class CoSecResponseInterceptor implements Interceptor {
|
|
|
26
24
|
* tokens are cleared and the original error is re-thrown.
|
|
27
25
|
*
|
|
28
26
|
* @param exchange - The fetch exchange containing the response to be processed
|
|
29
|
-
* @returns Promise<FetchExchange> The processed exchange, either with a refreshed token or original error
|
|
30
27
|
* @throws Error if token refresh fails or other errors occur during processing
|
|
31
28
|
*/
|
|
32
|
-
intercept(exchange: FetchExchange): Promise<
|
|
29
|
+
intercept(exchange: FetchExchange): Promise<void>;
|
|
33
30
|
}
|
|
34
31
|
//# sourceMappingURL=cosecResponseInterceptor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosecResponseInterceptor.d.ts","sourceRoot":"","sources":["../src/cosecResponseInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAiB,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEhE
|
|
1
|
+
{"version":3,"file":"cosecResponseInterceptor.d.ts","sourceRoot":"","sources":["../src/cosecResponseInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAiB,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;;;;;;GASG;AACH,qBAAa,wBAAyB,YAAW,WAAW;IAC1D,IAAI,SAA8B;IAClC,KAAK,SAAiC;IACtC,OAAO,CAAC,OAAO,CAAe;gBAElB,OAAO,EAAE,YAAY;IAIjC;;;;;;;;;;OAUG;IACG,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAsBxD"}
|
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
export declare const DEFAULT_COSEC_DEVICE_ID_KEY = "cosec-device-id";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Storage class for managing device identifiers.
|
|
4
4
|
*/
|
|
5
5
|
export declare class DeviceIdStorage {
|
|
6
6
|
private readonly deviceIdKey;
|
|
7
7
|
private storage;
|
|
8
8
|
constructor(deviceIdKey?: string, storage?: Storage);
|
|
9
9
|
/**
|
|
10
|
-
* Get the current device ID
|
|
10
|
+
* Get the current device ID.
|
|
11
|
+
*
|
|
12
|
+
* @returns The current device ID or null if not set
|
|
11
13
|
*/
|
|
12
14
|
get(): string | null;
|
|
13
15
|
/**
|
|
14
|
-
* Set a device ID
|
|
16
|
+
* Set a device ID.
|
|
17
|
+
*
|
|
18
|
+
* @param deviceId - The device ID to set
|
|
15
19
|
*/
|
|
16
20
|
set(deviceId: string): void;
|
|
17
21
|
/**
|
|
18
|
-
* Generate a new device ID
|
|
22
|
+
* Generate a new device ID.
|
|
23
|
+
*
|
|
24
|
+
* @returns A newly generated device ID
|
|
19
25
|
*/
|
|
20
26
|
generateDeviceId(): string;
|
|
21
27
|
/**
|
|
22
|
-
* Get or create a device ID
|
|
28
|
+
* Get or create a device ID.
|
|
29
|
+
*
|
|
30
|
+
* @returns The existing device ID if available, otherwise a newly generated one
|
|
23
31
|
*/
|
|
24
32
|
getOrCreate(): string;
|
|
25
33
|
/**
|
|
26
|
-
* Clear the stored device ID
|
|
34
|
+
* Clear the stored device ID.
|
|
27
35
|
*/
|
|
28
36
|
clear(): void;
|
|
29
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviceIdStorage.d.ts","sourceRoot":"","sources":["../src/deviceIdStorage.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAE7D;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,OAAO,CAAU;gBAGvB,WAAW,GAAE,MAAoC,EACjD,OAAO,GAAE,OAAsB;IAMjC
|
|
1
|
+
{"version":3,"file":"deviceIdStorage.d.ts","sourceRoot":"","sources":["../src/deviceIdStorage.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAE7D;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,OAAO,CAAU;gBAGvB,WAAW,GAAE,MAAoC,EACjD,OAAO,GAAE,OAAsB;IAMjC;;;;OAIG;IACH,GAAG,IAAI,MAAM,GAAG,IAAI;IAIpB;;;;OAIG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI3B;;;;OAIG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;;;OAIG;IACH,WAAW,IAAI,MAAM;IAYrB;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/idGenerator.d.ts
CHANGED
|
@@ -2,12 +2,14 @@ export interface IdGenerator {
|
|
|
2
2
|
generateId(): string;
|
|
3
3
|
}
|
|
4
4
|
/**
|
|
5
|
-
* Nano ID implementation of IdGenerator
|
|
6
|
-
* Generates unique request IDs using Nano ID
|
|
5
|
+
* Nano ID implementation of IdGenerator.
|
|
6
|
+
* Generates unique request IDs using Nano ID.
|
|
7
7
|
*/
|
|
8
8
|
export declare class NanoIdGenerator implements IdGenerator {
|
|
9
9
|
/**
|
|
10
|
-
* Generate a unique request ID
|
|
10
|
+
* Generate a unique request ID.
|
|
11
|
+
*
|
|
12
|
+
* @returns A unique request ID
|
|
11
13
|
*/
|
|
12
14
|
generateId(): string;
|
|
13
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idGenerator.d.ts","sourceRoot":"","sources":["../src/idGenerator.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,UAAU,IAAI,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD
|
|
1
|
+
{"version":3,"file":"idGenerator.d.ts","sourceRoot":"","sources":["../src/idGenerator.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,UAAU,IAAI,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD;;;;OAIG;IACH,UAAU,IAAI,MAAM;CAGrB;AAED,eAAO,MAAM,WAAW,iBAAwB,CAAC"}
|
package/dist/index.es.js
CHANGED
|
@@ -5,16 +5,18 @@ const S = {
|
|
|
5
5
|
IMPLICIT_DENY: { authorized: !1, reason: "Implicit Deny" },
|
|
6
6
|
TOKEN_EXPIRED: { authorized: !1, reason: "Token Expired" },
|
|
7
7
|
TOO_MANY_REQUESTS: { authorized: !1, reason: "Too Many Requests" }
|
|
8
|
-
},
|
|
8
|
+
}, u = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
9
9
|
let d = (t = 21) => {
|
|
10
10
|
let e = "", r = crypto.getRandomValues(new Uint8Array(t |= 0));
|
|
11
11
|
for (; t--; )
|
|
12
|
-
e +=
|
|
12
|
+
e += u[r[t] & 63];
|
|
13
13
|
return e;
|
|
14
14
|
};
|
|
15
15
|
class l {
|
|
16
16
|
/**
|
|
17
|
-
* Generate a unique request ID
|
|
17
|
+
* Generate a unique request ID.
|
|
18
|
+
*
|
|
19
|
+
* @returns A unique request ID
|
|
18
20
|
*/
|
|
19
21
|
generateId() {
|
|
20
22
|
return d();
|
|
@@ -26,7 +28,7 @@ class T {
|
|
|
26
28
|
this.name = "CoSecRequestInterceptor", this.order = Number.MIN_SAFE_INTEGER + 1e3, this.options = e;
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
|
-
* Intercept requests to add CoSec authentication headers
|
|
31
|
+
* Intercept requests to add CoSec authentication headers.
|
|
30
32
|
*
|
|
31
33
|
* This method adds the following headers to each request:
|
|
32
34
|
* - CoSec-App-Id: The application identifier from the CoSec options
|
|
@@ -34,8 +36,7 @@ class T {
|
|
|
34
36
|
* - CoSec-Request-Id: A unique identifier for this specific request
|
|
35
37
|
* - Authorization: Bearer token if available in token storage
|
|
36
38
|
*
|
|
37
|
-
* @param exchange - The fetch exchange containing the request to
|
|
38
|
-
* @returns The modified exchange with CoSec authentication headers added
|
|
39
|
+
* @param exchange - The fetch exchange containing the request to process
|
|
39
40
|
*/
|
|
40
41
|
intercept(e) {
|
|
41
42
|
const r = I.generateId(), n = this.options.deviceIdStorage.getOrCreate(), s = this.options.tokenStorage.get(), a = {
|
|
@@ -44,7 +45,7 @@ class T {
|
|
|
44
45
|
...e.request.headers
|
|
45
46
|
}
|
|
46
47
|
}, i = a.headers;
|
|
47
|
-
|
|
48
|
+
i[o.APP_ID] = this.options.appId, i[o.DEVICE_ID] = n, i[o.REQUEST_ID] = r, s && (i[o.AUTHORIZATION] = `Bearer ${s.accessToken}`), e.request = a;
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
class D {
|
|
@@ -52,7 +53,7 @@ class D {
|
|
|
52
53
|
this.name = "CoSecResponseInterceptor", this.order = Number.MAX_SAFE_INTEGER - 100, this.options = e;
|
|
53
54
|
}
|
|
54
55
|
/**
|
|
55
|
-
* Intercept responses to handle token refresh for unauthorized responses
|
|
56
|
+
* Intercept responses to handle token refresh for unauthorized responses.
|
|
56
57
|
*
|
|
57
58
|
* This method checks if a response has a 401 (UNAUTHORIZED) status code and attempts
|
|
58
59
|
* to refresh the authentication token if one is available. If token refresh is successful,
|
|
@@ -60,25 +61,23 @@ class D {
|
|
|
60
61
|
* tokens are cleared and the original error is re-thrown.
|
|
61
62
|
*
|
|
62
63
|
* @param exchange - The fetch exchange containing the response to be processed
|
|
63
|
-
* @returns Promise<FetchExchange> The processed exchange, either with a refreshed token or original error
|
|
64
64
|
* @throws Error if token refresh fails or other errors occur during processing
|
|
65
65
|
*/
|
|
66
66
|
async intercept(e) {
|
|
67
67
|
const r = e.response;
|
|
68
68
|
if (!r || r.status !== c.UNAUTHORIZED)
|
|
69
|
-
return
|
|
69
|
+
return;
|
|
70
70
|
const n = this.options.tokenStorage.get();
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
71
|
+
if (n)
|
|
72
|
+
try {
|
|
73
|
+
const s = await this.options.tokenRefresher.refresh(n);
|
|
74
|
+
this.options.tokenStorage.set(s), await e.fetcher.request(e.request);
|
|
75
|
+
} catch (s) {
|
|
76
|
+
throw this.options.tokenStorage.clear(), s;
|
|
77
|
+
}
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
|
-
class
|
|
80
|
+
class g {
|
|
82
81
|
constructor() {
|
|
83
82
|
this.store = /* @__PURE__ */ new Map();
|
|
84
83
|
}
|
|
@@ -102,41 +101,49 @@ class E {
|
|
|
102
101
|
this.store.set(e, r);
|
|
103
102
|
}
|
|
104
103
|
}
|
|
105
|
-
function
|
|
106
|
-
return typeof window < "u" && window.localStorage ? window.localStorage : new
|
|
104
|
+
function h() {
|
|
105
|
+
return typeof window < "u" && window.localStorage ? window.localStorage : new g();
|
|
107
106
|
}
|
|
108
|
-
const
|
|
107
|
+
const E = "cosec-device-id";
|
|
109
108
|
class y {
|
|
110
|
-
constructor(e =
|
|
109
|
+
constructor(e = E, r = h()) {
|
|
111
110
|
this.deviceIdKey = e, this.storage = r;
|
|
112
111
|
}
|
|
113
112
|
/**
|
|
114
|
-
* Get the current device ID
|
|
113
|
+
* Get the current device ID.
|
|
114
|
+
*
|
|
115
|
+
* @returns The current device ID or null if not set
|
|
115
116
|
*/
|
|
116
117
|
get() {
|
|
117
118
|
return this.storage.getItem(this.deviceIdKey);
|
|
118
119
|
}
|
|
119
120
|
/**
|
|
120
|
-
* Set a device ID
|
|
121
|
+
* Set a device ID.
|
|
122
|
+
*
|
|
123
|
+
* @param deviceId - The device ID to set
|
|
121
124
|
*/
|
|
122
125
|
set(e) {
|
|
123
126
|
this.storage.setItem(this.deviceIdKey, e);
|
|
124
127
|
}
|
|
125
128
|
/**
|
|
126
|
-
* Generate a new device ID
|
|
129
|
+
* Generate a new device ID.
|
|
130
|
+
*
|
|
131
|
+
* @returns A newly generated device ID
|
|
127
132
|
*/
|
|
128
133
|
generateDeviceId() {
|
|
129
134
|
return I.generateId();
|
|
130
135
|
}
|
|
131
136
|
/**
|
|
132
|
-
* Get or create a device ID
|
|
137
|
+
* Get or create a device ID.
|
|
138
|
+
*
|
|
139
|
+
* @returns The existing device ID if available, otherwise a newly generated one
|
|
133
140
|
*/
|
|
134
141
|
getOrCreate() {
|
|
135
142
|
let e = this.get();
|
|
136
143
|
return e || (e = this.generateDeviceId(), this.set(e)), e;
|
|
137
144
|
}
|
|
138
145
|
/**
|
|
139
|
-
* Clear the stored device ID
|
|
146
|
+
* Clear the stored device ID.
|
|
140
147
|
*/
|
|
141
148
|
clear() {
|
|
142
149
|
this.storage.removeItem(this.deviceIdKey);
|
|
@@ -144,25 +151,29 @@ class y {
|
|
|
144
151
|
}
|
|
145
152
|
const p = "cosec-token";
|
|
146
153
|
class A {
|
|
147
|
-
constructor(e = p, r =
|
|
154
|
+
constructor(e = p, r = h()) {
|
|
148
155
|
this.tokenKey = e, this.storage = r;
|
|
149
156
|
}
|
|
150
157
|
/**
|
|
151
|
-
* Get the current access token
|
|
158
|
+
* Get the current access token.
|
|
159
|
+
*
|
|
160
|
+
* @returns The current composite token or null if not set
|
|
152
161
|
*/
|
|
153
162
|
get() {
|
|
154
163
|
const e = this.storage.getItem(this.tokenKey);
|
|
155
164
|
return e ? JSON.parse(e) : null;
|
|
156
165
|
}
|
|
157
166
|
/**
|
|
158
|
-
* Store a composite token
|
|
167
|
+
* Store a composite token.
|
|
168
|
+
*
|
|
169
|
+
* @param token - The composite token to store
|
|
159
170
|
*/
|
|
160
171
|
set(e) {
|
|
161
172
|
const r = JSON.stringify(e);
|
|
162
173
|
this.storage.setItem(this.tokenKey, r);
|
|
163
174
|
}
|
|
164
175
|
/**
|
|
165
|
-
* Clear all tokens
|
|
176
|
+
* Clear all tokens.
|
|
166
177
|
*/
|
|
167
178
|
clear() {
|
|
168
179
|
this.storage.removeItem(this.tokenKey);
|
|
@@ -173,13 +184,13 @@ export {
|
|
|
173
184
|
o as CoSecHeaders,
|
|
174
185
|
T as CoSecRequestInterceptor,
|
|
175
186
|
D as CoSecResponseInterceptor,
|
|
176
|
-
|
|
187
|
+
E as DEFAULT_COSEC_DEVICE_ID_KEY,
|
|
177
188
|
p as DEFAULT_COSEC_TOKEN_KEY,
|
|
178
189
|
y as DeviceIdStorage,
|
|
179
|
-
|
|
190
|
+
g as InMemoryStorage,
|
|
180
191
|
l as NanoIdGenerator,
|
|
181
192
|
c as ResponseCodes,
|
|
182
193
|
A as TokenStorage,
|
|
183
|
-
|
|
194
|
+
h as getStorage,
|
|
184
195
|
I as idGenerator
|
|
185
196
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(r,s){typeof exports=="object"&&typeof module<"u"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(r=typeof globalThis<"u"?globalThis:r||self,s(r.FetcherCoSec={}))})(this,(function(r){"use strict";var s=(t=>(t.DEVICE_ID="CoSec-Device-Id",t.APP_ID="CoSec-App-Id",t.AUTHORIZATION="Authorization",t.REQUEST_ID="CoSec-Request-Id",t))(s||{}),c=(t=>(t[t.UNAUTHORIZED=401]="UNAUTHORIZED",t))(c||{});const S={ALLOW:{authorized:!0,reason:"Allow"},EXPLICIT_DENY:{authorized:!1,reason:"Explicit Deny"},IMPLICIT_DENY:{authorized:!1,reason:"Implicit Deny"},TOKEN_EXPIRED:{authorized:!1,reason:"Token Expired"},TOO_MANY_REQUESTS:{authorized:!1,reason:"Too Many Requests"}},T="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";let f=(t=21)=>{let e="",o=crypto.getRandomValues(new Uint8Array(t|=0));for(;t--;)e+=T[o[t]&63];return e};class d{generateId(){return f()}}const
|
|
1
|
+
(function(r,s){typeof exports=="object"&&typeof module<"u"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(r=typeof globalThis<"u"?globalThis:r||self,s(r.FetcherCoSec={}))})(this,(function(r){"use strict";var s=(t=>(t.DEVICE_ID="CoSec-Device-Id",t.APP_ID="CoSec-App-Id",t.AUTHORIZATION="Authorization",t.REQUEST_ID="CoSec-Request-Id",t))(s||{}),c=(t=>(t[t.UNAUTHORIZED=401]="UNAUTHORIZED",t))(c||{});const S={ALLOW:{authorized:!0,reason:"Allow"},EXPLICIT_DENY:{authorized:!1,reason:"Explicit Deny"},IMPLICIT_DENY:{authorized:!1,reason:"Implicit Deny"},TOKEN_EXPIRED:{authorized:!1,reason:"Token Expired"},TOO_MANY_REQUESTS:{authorized:!1,reason:"Too Many Requests"}},T="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";let f=(t=21)=>{let e="",o=crypto.getRandomValues(new Uint8Array(t|=0));for(;t--;)e+=T[o[t]&63];return e};class d{generateId(){return f()}}const I=new d;class p{constructor(e){this.name="CoSecRequestInterceptor",this.order=Number.MIN_SAFE_INTEGER+1e3,this.options=e}intercept(e){const o=I.generateId(),i=this.options.deviceIdStorage.getOrCreate(),n=this.options.tokenStorage.get(),g={...e.request,headers:{...e.request.headers}},a=g.headers;a[s.APP_ID]=this.options.appId,a[s.DEVICE_ID]=i,a[s.REQUEST_ID]=o,n&&(a[s.AUTHORIZATION]=`Bearer ${n.accessToken}`),e.request=g}}class D{constructor(e){this.name="CoSecResponseInterceptor",this.order=Number.MAX_SAFE_INTEGER-100,this.options=e}async intercept(e){const o=e.response;if(!o||o.status!==c.UNAUTHORIZED)return;const i=this.options.tokenStorage.get();if(i)try{const n=await this.options.tokenRefresher.refresh(i);this.options.tokenStorage.set(n),await e.fetcher.request(e.request)}catch(n){throw this.options.tokenStorage.clear(),n}}}class h{constructor(){this.store=new Map}get length(){return this.store.size}clear(){this.store.clear()}getItem(e){const o=this.store.get(e);return o!==void 0?o:null}key(e){return Array.from(this.store.keys())[e]||null}removeItem(e){this.store.has(e)&&this.store.delete(e)}setItem(e,o){this.store.set(e,o)}}function u(){return typeof window<"u"&&window.localStorage?window.localStorage:new h}const l="cosec-device-id";class _{constructor(e=l,o=u()){this.deviceIdKey=e,this.storage=o}get(){return this.storage.getItem(this.deviceIdKey)}set(e){this.storage.setItem(this.deviceIdKey,e)}generateDeviceId(){return I.generateId()}getOrCreate(){let e=this.get();return e||(e=this.generateDeviceId(),this.set(e)),e}clear(){this.storage.removeItem(this.deviceIdKey)}}const E="cosec-token";class y{constructor(e=E,o=u()){this.tokenKey=e,this.storage=o}get(){const e=this.storage.getItem(this.tokenKey);return e?JSON.parse(e):null}set(e){const o=JSON.stringify(e);this.storage.setItem(this.tokenKey,o)}clear(){this.storage.removeItem(this.tokenKey)}}r.AuthorizeResults=S,r.CoSecHeaders=s,r.CoSecRequestInterceptor=p,r.CoSecResponseInterceptor=D,r.DEFAULT_COSEC_DEVICE_ID_KEY=l,r.DEFAULT_COSEC_TOKEN_KEY=E,r.DeviceIdStorage=_,r.InMemoryStorage=h,r.NanoIdGenerator=d,r.ResponseCodes=c,r.TokenStorage=y,r.getStorage=u,r.idGenerator=I,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/tokenRefresher.d.ts
CHANGED
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Interface for access tokens.
|
|
3
3
|
*/
|
|
4
4
|
export interface AccessToken {
|
|
5
5
|
accessToken: string;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Interface for refresh tokens.
|
|
9
9
|
*/
|
|
10
10
|
export interface RefreshToken {
|
|
11
11
|
refreshToken: string;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* Composite token interface that contains both access and refresh tokens
|
|
15
|
-
*
|
|
14
|
+
* Composite token interface that contains both access and refresh tokens.
|
|
15
|
+
*
|
|
16
|
+
* accessToken and refreshToken always appear in pairs, no need to split them.
|
|
16
17
|
*/
|
|
17
18
|
export interface CompositeToken extends AccessToken, RefreshToken {
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
21
|
+
* Interface for token refreshers.
|
|
22
|
+
*
|
|
23
|
+
* Provides a method to refresh tokens.
|
|
22
24
|
*/
|
|
23
25
|
export interface TokenRefresher {
|
|
24
26
|
/**
|
|
25
|
-
* Refresh the given token and return a new CompositeToken
|
|
27
|
+
* Refresh the given token and return a new CompositeToken.
|
|
28
|
+
*
|
|
26
29
|
* @param token The token to refresh
|
|
27
30
|
* @returns A Promise that resolves to a new CompositeToken
|
|
28
31
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenRefresher.d.ts","sourceRoot":"","sources":["../src/tokenRefresher.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED
|
|
1
|
+
{"version":3,"file":"tokenRefresher.d.ts","sourceRoot":"","sources":["../src/tokenRefresher.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAe,SAAQ,WAAW,EAAE,YAAY;CAAG;AAEpE;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACzD"}
|
package/dist/tokenStorage.d.ts
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { CompositeToken } from './tokenRefresher';
|
|
2
2
|
export declare const DEFAULT_COSEC_TOKEN_KEY = "cosec-token";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Storage class for managing access and refresh tokens.
|
|
5
5
|
*/
|
|
6
6
|
export declare class TokenStorage {
|
|
7
7
|
private readonly tokenKey;
|
|
8
8
|
private storage;
|
|
9
9
|
constructor(tokenKey?: string, storage?: Storage);
|
|
10
10
|
/**
|
|
11
|
-
* Get the current access token
|
|
11
|
+
* Get the current access token.
|
|
12
|
+
*
|
|
13
|
+
* @returns The current composite token or null if not set
|
|
12
14
|
*/
|
|
13
15
|
get(): CompositeToken | null;
|
|
14
16
|
/**
|
|
15
|
-
* Store a composite token
|
|
17
|
+
* Store a composite token.
|
|
18
|
+
*
|
|
19
|
+
* @param token - The composite token to store
|
|
16
20
|
*/
|
|
17
21
|
set(token: CompositeToken): void;
|
|
18
22
|
/**
|
|
19
|
-
* Clear all tokens
|
|
23
|
+
* Clear all tokens.
|
|
20
24
|
*/
|
|
21
25
|
clear(): void;
|
|
22
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenStorage.d.ts","sourceRoot":"","sources":["../src/tokenStorage.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,uBAAuB,gBAAgB,CAAC;AAErD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,OAAO,CAAU;gBAGvB,QAAQ,GAAE,MAAgC,EAC1C,OAAO,GAAE,OAAsB;IAMjC
|
|
1
|
+
{"version":3,"file":"tokenStorage.d.ts","sourceRoot":"","sources":["../src/tokenStorage.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,uBAAuB,gBAAgB,CAAC;AAErD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,OAAO,CAAU;gBAGvB,QAAQ,GAAE,MAAgC,EAC1C,OAAO,GAAE,OAAsB;IAMjC;;;;OAIG;IACH,GAAG,IAAI,cAAc,GAAG,IAAI;IAK5B;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAKhC;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { DeviceIdStorage } from './deviceIdStorage';
|
|
|
2
2
|
import { TokenStorage } from './tokenStorage';
|
|
3
3
|
import { TokenRefresher } from './tokenRefresher';
|
|
4
4
|
/**
|
|
5
|
-
* CoSec HTTP headers enumeration
|
|
5
|
+
* CoSec HTTP headers enumeration.
|
|
6
6
|
*/
|
|
7
7
|
export declare enum CoSecHeaders {
|
|
8
8
|
DEVICE_ID = "CoSec-Device-Id",
|
|
@@ -14,36 +14,37 @@ export declare enum ResponseCodes {
|
|
|
14
14
|
UNAUTHORIZED = 401
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* CoSec options interface
|
|
17
|
+
* CoSec options interface.
|
|
18
18
|
*/
|
|
19
19
|
export interface CoSecOptions {
|
|
20
20
|
/**
|
|
21
|
-
* Application ID to be sent in the CoSec-App-Id header
|
|
21
|
+
* Application ID to be sent in the CoSec-App-Id header.
|
|
22
22
|
*/
|
|
23
23
|
appId: string;
|
|
24
24
|
/**
|
|
25
|
-
* Device ID storage instance
|
|
25
|
+
* Device ID storage instance.
|
|
26
26
|
*/
|
|
27
27
|
deviceIdStorage: DeviceIdStorage;
|
|
28
28
|
/**
|
|
29
|
-
* Token storage instance
|
|
29
|
+
* Token storage instance.
|
|
30
30
|
*/
|
|
31
31
|
tokenStorage: TokenStorage;
|
|
32
32
|
/**
|
|
33
|
-
* Token refresher function
|
|
34
|
-
*
|
|
33
|
+
* Token refresher function.
|
|
34
|
+
*
|
|
35
|
+
* Takes a CompositeToken and returns a Promise that resolves to a new CompositeToken.
|
|
35
36
|
*/
|
|
36
37
|
tokenRefresher: TokenRefresher;
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
|
-
* Authorization result interface
|
|
40
|
+
* Authorization result interface.
|
|
40
41
|
*/
|
|
41
42
|
export interface AuthorizeResult {
|
|
42
43
|
authorized: boolean;
|
|
43
44
|
reason: string;
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
|
-
* Authorization result constants
|
|
47
|
+
* Authorization result constants.
|
|
47
48
|
*/
|
|
48
49
|
export declare const AuthorizeResults: {
|
|
49
50
|
ALLOW: {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;GAEG;AACH,oBAAY,YAAY;IACtB,SAAS,oBAAoB;IAC7B,MAAM,iBAAiB;IACvB,aAAa,kBAAkB;IAC/B,UAAU,qBAAqB;CAChC;AAED,oBAAY,aAAa;IACvB,YAAY,MAAM;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,eAAe,EAAE,eAAe,CAAC;IAEjC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;IAE3B
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;GAEG;AACH,oBAAY,YAAY;IACtB,SAAS,oBAAoB;IAC7B,MAAM,iBAAiB;IACvB,aAAa,kBAAkB;IAC/B,UAAU,qBAAqB;CAChC;AAED,oBAAY,aAAa;IACvB,YAAY,MAAM;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,eAAe,EAAE,eAAe,CAAC;IAEjC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;IAE3B;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;CAM5B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahoo-wang/fetcher-cosec",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "CoSec authentication integration for Fetcher HTTP client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fetch",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"nanoid": "^5.1.5",
|
|
38
|
-
"@ahoo-wang/fetcher": "0.
|
|
38
|
+
"@ahoo-wang/fetcher": "0.9.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@vitest/coverage-v8": "^3.2.4",
|