@conduit-client/jwt-manager 5.67.0-dev1

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/LICENSE.txt ADDED
@@ -0,0 +1,27 @@
1
+ *Attorney/Client Privileged + Confidential*
2
+
3
+ Terms of Use for Public Code (Non-OSS)
4
+
5
+ *NOTE:* Before publishing code under this license/these Terms of Use, please review https://salesforce.quip.com/WFfvAMKB18AL and confirm that you’ve completed all prerequisites described therein. *These Terms of Use may not be used or modified without input from IP and Product Legal.*
6
+
7
+ *Terms of Use*
8
+
9
+ Copyright 2022 Salesforce, Inc. All rights reserved.
10
+
11
+ These Terms of Use govern the download, installation, and/or use of this software provided by Salesforce, Inc. (“Salesforce”) (the “Software”), were last updated on April 15, 2022, ** and constitute a legally binding agreement between you and Salesforce. If you do not agree to these Terms of Use, do not install or use the Software.
12
+
13
+ Salesforce grants you a worldwide, non-exclusive, no-charge, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute the Software and derivative works subject to these Terms. These Terms shall be included in all copies or substantial portions of the Software.
14
+
15
+ Subject to the limited rights expressly granted hereunder, Salesforce reserves all rights, title, and interest in and to all intellectual property subsisting in the Software. No rights are granted to you hereunder other than as expressly set forth herein. Users residing in countries on the United States Office of Foreign Assets Control sanction list, or which are otherwise subject to a US export embargo, may not use the Software.
16
+
17
+ Implementation of the Software may require development work, for which you are responsible. The Software may contain bugs, errors and incompatibilities and is made available on an AS IS basis without support, updates, or service level commitments.
18
+
19
+ Salesforce reserves the right at any time to modify, suspend, or discontinue, the Software (or any part thereof) with or without notice. You agree that Salesforce shall not be liable to you or to any third party for any modification, suspension, or discontinuance.
20
+
21
+ You agree to defend Salesforce against any claim, demand, suit or proceeding made or brought against Salesforce by a third party arising out of or accruing from (a) your use of the Software, and (b) any application you develop with the Software that infringes any copyright, trademark, trade secret, trade dress, patent, or other intellectual property right of any person or defames any person or violates their rights of publicity or privacy (each a “Claim Against Salesforce”), and will indemnify Salesforce from any damages, attorney fees, and costs finally awarded against Salesforce as a result of, or for any amounts paid by Salesforce under a settlement approved by you in writing of, a Claim Against Salesforce, provided Salesforce (x) promptly gives you written notice of the Claim Against Salesforce, (y) gives you sole control of the defense and settlement of the Claim Against Salesforce (except that you may not settle any Claim Against Salesforce unless it unconditionally releases Salesforce of all liability), and (z) gives you all reasonable assistance, at your expense.
22
+
23
+ WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE SOFTWARE IS NOT SUPPORTED AND IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. IN NO EVENT SHALL SALESFORCE HAVE ANY LIABILITY FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES, OR DAMAGES BASED ON LOST PROFITS, DATA, OR USE, IN CONNECTION WITH THE SOFTWARE, HOWEVER CAUSED AND WHETHER IN CONTRACT, TORT, OR UNDER ANY OTHER THEORY OF LIABILITY, WHETHER OR NOT YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
24
+
25
+ These Terms of Use shall be governed exclusively by the internal laws of the State of California, without regard to its conflicts of laws rules. Each party hereby consents to the exclusive jurisdiction of the state and federal courts located in San Francisco County, California to adjudicate any dispute arising out of or relating to these Terms of Use and the download, installation, and/or use of the Software. Except as expressly stated herein, these Terms of Use constitute the entire agreement between the parties, and supersede all prior and contemporaneous agreements, proposals, or representations, written or oral, concerning their subject matter. No modification, amendment, or waiver of any provision of these Terms of Use shall be effective unless it is by an update to these Terms of Use that Salesforce makes available, or is in writing and signed by the party against whom the modification, amendment, or waiver is to be asserted.
26
+
27
+ _*Data Privacy*_: Salesforce may collect, process, and store device, system, and other information related to your use of the Software. This information includes, but is not limited to, IP address, user metrics, and other data (“Usage Data”). Salesforce may use Usage Data for analytics, product development, and marketing purposes. You acknowledge that files generated in conjunction with the Software may contain sensitive or confidential data, and you are solely responsible for anonymizing and protecting such data.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # JWT Manager
2
+
3
+ JWT Manager is a package that simplifies the handling of JWT (JSON Web Tokens) in your application. It abstracts the process of retrieving, storing, and refreshing tokens with a clean and straightforward API.
4
+
5
+ ## Installation
6
+
7
+ You can add JWT Manager to your project using npm:
8
+
9
+ ```bash
10
+ npm install -client/jwt-manager
11
+ ```
12
+
13
+ ## Features
14
+
15
+ - Get and refresh JWTs easily with `getJwt` and `refreshToken` methods.
16
+ - Handle token expiration with automatic refresh.
17
+ - Utilizes `JwtRepository` for token storage and management.
18
+ - Works with a `JwtResolver` to retrieve tokens.
19
+ - Allows additional extra info along with the token.
20
+
21
+ ## Usage
22
+
23
+ Here is a basic example of using JWT Manager in a Node.js application:
24
+
25
+ ```javascript
26
+ const { JwtManager, JwtRepository, JwtResolver } = require('@conduit-client/jwt-manager');
27
+
28
+ type EncodedJwtClaims = {
29
+ exp: number;
30
+ username: string;
31
+ }
32
+ type ExtraInfo = {
33
+ envBaseUri: string;
34
+ }
35
+ // Your JwtResolver implementation
36
+ const jwtResolver: JwtResolver<ExtraInfo> = {
37
+ getJwt(): Promise<{ jwt: string; extraInfo: ExtraInfo }> {
38
+ return fetch(); // resolves the jwt.
39
+ }
40
+ };
41
+
42
+ // Your JwtRepository implementation
43
+ const jwtRepository = new JwtRepository<EncodedJwtClaims, ExtraInfo>(
44
+ 3, // notifies that the token will expire in 3 seconds
45
+ 120, // if exp claim is not provided, the token will expire in 120 seconds.
46
+ );
47
+
48
+ // Create JwtManager instance
49
+ const jwtManager = new JwtManager(jwtRepository, jwtResolver);
50
+
51
+ // Get a JWT
52
+ jwtManager.getJwt().then((jwt) => {
53
+ console.log(jwt.token); // Prints the JWT
54
+ console.log(jwt.decodedInfo); // Prints the JWT decoded information
55
+ console.log(jwt.extraInfo); // Prints the JWT extra information
56
+ });
57
+ ```
58
+
59
+ Remember that you will need to provide your own `JwtResolver` implementation of the `JwtResolver` interface. The `JwtResolver` should provide a `getJwt` method that retrieves a new JWT (and optionally extra info) when needed.
60
+
61
+ ## API Reference
62
+
63
+ The package exports two main elements: `JwtManager` class, `JwtRepository` class and `JwtResolver` and `JwtToken` types.
64
+
65
+ ### JwtManager
66
+
67
+ The `JwtManager` class is the main class in the JWT Manager package.
68
+
69
+ It exposes the following methods:
70
+
71
+ - `getJwt()`: Returns a JWT. If a token request is in progress, it returns the Promise of this request. If the current token is undefined or expired, it initiates a token refresh. Otherwise, it returns the current token.
72
+ - `refreshToken()`: Refreshes a JWT. If a refresh request is already in progress, it returns the Promise of this request. Otherwise, it starts a new refresh request and returns its Promise.
73
+
74
+ ### JWT Repository
75
+
76
+ The `JwtRepository` class is a storage and management solution for JWT (JSON Web Tokens) within the JWT Manager package.
77
+
78
+ The class handles:
79
+
80
+ - Setting and getting the current JWT.
81
+ - Notifying observers when the JWT is nearing its expiration.
82
+ - Removing the JWT.
83
+
84
+ #### Usage
85
+
86
+ ```javascript
87
+ const { JwtRepository } = require('jwt-manager');
88
+
89
+ // Create JwtRepository instance with optional parameters
90
+ const jwtRepository = new JwtRepository(limitInSeconds, defaultTokenTTLInSeconds, logger);
91
+
92
+ // Set a JWT with optional extra information
93
+ jwtRepository.setToken('myJWT', { extra: 'info' });
94
+
95
+ // Get the current JWT
96
+ const currentToken = jwtRepository.token;
97
+
98
+ // Subscribe to the token nearing its expiration
99
+ const unsubscribe = jwtRepository.subscribeToTokenNearExpiration((token) => {
100
+ console.log(`Token is about to expire: ${token}`);
101
+ });
102
+
103
+ // To unsubscribe
104
+ unsubscribe();
105
+
106
+ // Remove the current JWT
107
+ jwtRepository.removeToken();
108
+ ```
109
+
110
+ #### API
111
+
112
+ `JwtRepository` exposes the following methods:
113
+
114
+ - `constructor(limitInSeconds: number, defaultTokenTTLInSeconds: number, logger: Logger)`: The constructor takes optional parameters to customize its behavior. The `limitInSeconds` sets the time before the token's expiry to notify observers. The `defaultTokenTTLInSeconds` sets the default token expiry time in seconds if "exp" claim is not present in the token. `logger` is used for logging warnings and errors.
115
+
116
+ - `token`: Returns the current JWT.
117
+
118
+ - `setToken(token: string, extraInfo?: ExtraInfo)`: Sets the current JWT with optional extra information. Returns an object of the set token.
119
+
120
+ - `removeToken()`: Removes the current JWT.
121
+
122
+ - `subscribeToTokenNearExpiration(cb: (token: JwtToken<T, ExtraInfo>) => void)`: Subscribes to the token nearing its expiration. It returns a function that can be used to unsubscribe.
123
+
124
+ ### JwtResolver
125
+
126
+ The `JwtResolver` type is used to define the structure for JWT resolver instances. It contains a `getJwt` method that should return a Promise with a JWT and optionally extra information.
127
+
128
+ ## Contributing
129
+
130
+ We welcome contributions! Please see our [contributing guide](/CONTRIBUTING.md) for more details.
131
+
132
+ ## License
133
+
134
+ see the [LICENSE.txt](./LICENSE.txt) file for details.
package/dist/index.js ADDED
@@ -0,0 +1,339 @@
1
+ /*!
2
+ * Copyright (c) 2022, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ function e(e2) {
7
+ this.message = e2;
8
+ }
9
+ e.prototype = new Error(), e.prototype.name = "InvalidCharacterError";
10
+ var r = "undefined" != typeof window && window.atob && window.atob.bind(window) || function(r2) {
11
+ var t2 = String(r2).replace(/=+$/, "");
12
+ if (t2.length % 4 == 1) throw new e("'atob' failed: The string to be decoded is not correctly encoded.");
13
+ for (var n2, o2, a = 0, i = 0, c = ""; o2 = t2.charAt(i++); ~o2 && (n2 = a % 4 ? 64 * n2 + o2 : o2, a++ % 4) ? c += String.fromCharCode(255 & n2 >> (-2 * a & 6)) : 0) o2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(o2);
14
+ return c;
15
+ };
16
+ function t(e2) {
17
+ var t2 = e2.replace(/-/g, "+").replace(/_/g, "/");
18
+ switch (t2.length % 4) {
19
+ case 0:
20
+ break;
21
+ case 2:
22
+ t2 += "==";
23
+ break;
24
+ case 3:
25
+ t2 += "=";
26
+ break;
27
+ default:
28
+ throw "Illegal base64url string!";
29
+ }
30
+ try {
31
+ return (function(e3) {
32
+ return decodeURIComponent(r(e3).replace(/(.)/g, (function(e4, r2) {
33
+ var t3 = r2.charCodeAt(0).toString(16).toUpperCase();
34
+ return t3.length < 2 && (t3 = "0" + t3), "%" + t3;
35
+ })));
36
+ })(t2);
37
+ } catch (e3) {
38
+ return r(t2);
39
+ }
40
+ }
41
+ function n(e2) {
42
+ this.message = e2;
43
+ }
44
+ function o(e2, r2) {
45
+ if ("string" != typeof e2) throw new n("Invalid token specified");
46
+ var o2 = true === (r2 = r2 || {}).header ? 0 : 1;
47
+ try {
48
+ return JSON.parse(t(e2.split(".")[o2]));
49
+ } catch (e3) {
50
+ throw new n("Invalid token specified: " + e3.message);
51
+ }
52
+ }
53
+ n.prototype = new Error(), n.prototype.name = "InvalidTokenError";
54
+ /*!
55
+ * Copyright (c) 2022, Salesforce, Inc.,
56
+ * All rights reserved.
57
+ * For full license text, see the LICENSE.txt file
58
+ */
59
+ const LogLevelMap = {
60
+ TRACE: 4,
61
+ DEBUG: 3,
62
+ INFO: 2,
63
+ WARN: 1,
64
+ ERROR: 0
65
+ };
66
+ class ConsoleLogger {
67
+ constructor(level = "WARN", printer = console.log, formatter = (level2, message) => `${level2}: ${message}`) {
68
+ this.level = level;
69
+ this.printer = printer;
70
+ this.formatter = formatter;
71
+ this.messages = [];
72
+ }
73
+ trace(message) {
74
+ this.log("TRACE", message);
75
+ }
76
+ debug(message) {
77
+ this.log("DEBUG", message);
78
+ }
79
+ info(message) {
80
+ this.log("INFO", message);
81
+ }
82
+ warn(message) {
83
+ this.log("WARN", message);
84
+ }
85
+ error(message) {
86
+ this.log("ERROR", message);
87
+ }
88
+ log(level, message) {
89
+ if (LogLevelMap[level] > LogLevelMap[this.level]) {
90
+ return;
91
+ }
92
+ this.printer(this.formatter(level, message));
93
+ }
94
+ }
95
+ function loggerService(level, printer, formatter) {
96
+ return new ConsoleLogger(level, printer, formatter);
97
+ }
98
+ class JwtToken {
99
+ /**
100
+ * Create a new JwtToken.
101
+ *
102
+ * @param _token - The JWT string.
103
+ * @param _decodedInfo - The decoded information from the JWT.
104
+ * @param _extraInfo - Any additional information associated with the JWT.
105
+ */
106
+ constructor(_token, _decodedInfo, _extraInfo) {
107
+ this._token = _token;
108
+ this._decodedInfo = _decodedInfo;
109
+ this._extraInfo = _extraInfo;
110
+ }
111
+ /**
112
+ * Get the JWT string.
113
+ *
114
+ * @returns The JWT string.
115
+ */
116
+ get token() {
117
+ return this._token;
118
+ }
119
+ /**
120
+ * Get the additional information associated with the JWT.
121
+ *
122
+ * @returns The additional information.
123
+ */
124
+ get extraInfo() {
125
+ return this._extraInfo;
126
+ }
127
+ /**
128
+ * Get the decoded information from the JWT.
129
+ *
130
+ * @returns The decoded information.
131
+ */
132
+ get decodedInfo() {
133
+ return this._decodedInfo;
134
+ }
135
+ /**
136
+ * Get the remaining time in seconds until the JWT expires.
137
+ *
138
+ * @returns The remaining time in seconds.
139
+ */
140
+ get tokenRemainingSeconds() {
141
+ return this.decodedInfo.exp - Date.now() / 1e3;
142
+ }
143
+ /**
144
+ * Check if the JWT is expired.
145
+ *
146
+ * @returns True if the JWT is expired, false otherwise.
147
+ */
148
+ get isExpired() {
149
+ return this.tokenRemainingSeconds <= 0;
150
+ }
151
+ }
152
+ let defaultLogger = {
153
+ trace: () => {
154
+ },
155
+ debug: () => {
156
+ },
157
+ info: () => {
158
+ },
159
+ warn: () => {
160
+ },
161
+ error: () => {
162
+ }
163
+ };
164
+ if (process.env.NODE_ENV !== "production") {
165
+ defaultLogger = loggerService();
166
+ }
167
+ function computeDecodedInfo(token, defaultTokenTTLInSeconds, logger) {
168
+ const decodedInfo = o(token);
169
+ if (decodedInfo.exp === void 0) {
170
+ logger.warn(`"exp" claim is not present in the provided token.`);
171
+ decodedInfo.exp = Date.now() / 1e3 + defaultTokenTTLInSeconds;
172
+ }
173
+ return decodedInfo;
174
+ }
175
+ class JwtRepository {
176
+ /**
177
+ * @param limitInSeconds - Time in seconds before the token's expiry to notify observers.
178
+ * @param defaultTokenTTLInSeconds - Default token expiry time in seconds if "exp" claim is not present in token.
179
+ * @param logger - Logger for logging warnings and errors.
180
+ */
181
+ constructor(limitInSeconds = 5, defaultTokenTTLInSeconds = 120, logger = defaultLogger) {
182
+ this.limitInSeconds = limitInSeconds;
183
+ this.defaultTokenTTLInSeconds = defaultTokenTTLInSeconds;
184
+ this.logger = logger;
185
+ this.observers = [];
186
+ }
187
+ /**
188
+ * Get the current token.
189
+ */
190
+ get token() {
191
+ return this._token;
192
+ }
193
+ /**
194
+ * Set the current token.
195
+ *
196
+ * @param token - JWT token as a string.
197
+ * @param extraInfo - Optional extra information.
198
+ */
199
+ setToken(token, extraInfo) {
200
+ const decodedInfo = computeDecodedInfo(
201
+ token,
202
+ this.defaultTokenTTLInSeconds,
203
+ this.logger
204
+ );
205
+ this._token = new JwtToken(token, decodedInfo, extraInfo);
206
+ this.observeTokenExpiration();
207
+ return this._token;
208
+ }
209
+ /**
210
+ * Remove the current token.
211
+ */
212
+ removeToken() {
213
+ this._token = void 0;
214
+ this.clearTimeoutHandler();
215
+ }
216
+ /**
217
+ * Subscribe to the token nearing its expiration.
218
+ *
219
+ * @param cb - Callback function to execute when token is nearing expiration.
220
+ */
221
+ subscribeToTokenNearExpiration(cb) {
222
+ this.observers.push(cb);
223
+ this.observeTokenExpiration();
224
+ return () => {
225
+ this.observers = this.observers.filter((observer) => observer !== cb);
226
+ };
227
+ }
228
+ /**
229
+ * Clear the timeout handler.
230
+ */
231
+ clearTimeoutHandler() {
232
+ if (this.timeoutHandler !== void 0) {
233
+ clearTimeout(this.timeoutHandler);
234
+ }
235
+ }
236
+ /**
237
+ * Observe and handle token expiration.
238
+ */
239
+ observeTokenExpiration() {
240
+ this.clearTimeoutHandler();
241
+ if (this.observers.length === 0 || this.token === void 0) {
242
+ return;
243
+ }
244
+ this.timeoutHandler = setTimeout(
245
+ () => this.notifyTokenIsExpiring(),
246
+ this.computeTimeoutTimeInMs()
247
+ );
248
+ }
249
+ /**
250
+ * Compute the timeout time in milliseconds.
251
+ */
252
+ computeTimeoutTimeInMs() {
253
+ const remainingSeconds = this.token.tokenRemainingSeconds;
254
+ let timeoutTimeInSeconds = remainingSeconds - this.limitInSeconds;
255
+ return timeoutTimeInSeconds < 0 ? 0 : timeoutTimeInSeconds * 1e3;
256
+ }
257
+ /**
258
+ * Notify all observers that the token is expiring.
259
+ */
260
+ notifyTokenIsExpiring() {
261
+ this.observers.forEach((cb) => {
262
+ try {
263
+ cb.call(void 0, this.token);
264
+ } catch (e2) {
265
+ this.logger.error(e2.message);
266
+ }
267
+ });
268
+ }
269
+ }
270
+ class JwtManager {
271
+ /**
272
+ * Constructor for JwtManager class.
273
+ *
274
+ * @param {JwtRepository<T, ExtraInfo>} jwtRepository JwtRepository instance used for token management.
275
+ * @param {JwtResolver<ExtraInfo>} resolver JwtResolver instance used for token retrieval.
276
+ * @param {JwtManagerOptions} options JwtManagerOptions bag to customize behavior.
277
+ */
278
+ constructor(jwtRepository, resolver, options) {
279
+ this.jwtRepository = jwtRepository;
280
+ this.resolver = resolver;
281
+ if (options == null ? void 0 : options.keepTokenUpdated) {
282
+ jwtRepository.subscribeToTokenNearExpiration(() => this.refreshToken());
283
+ }
284
+ }
285
+ /**
286
+ * Method to get a JWT token.
287
+ * If there's a token request in progress, it will return the Promise of this request.
288
+ * If the current token is undefined or expired, it will initiate a token refresh.
289
+ * Otherwise, it will return the current token.
290
+ *
291
+ * @returns {JwtToken<T, ExtraInfo> | Promise<JwtToken<T, ExtraInfo>>} The current token or the Promise of a token request.
292
+ */
293
+ getJwt() {
294
+ if (this.inflightPromise) {
295
+ return this.inflightPromise;
296
+ }
297
+ const token = this.jwtRepository.token;
298
+ if (token === void 0 || token.isExpired) {
299
+ return this.refreshToken();
300
+ }
301
+ return token;
302
+ }
303
+ /**
304
+ * Method to refresh a JWT token.
305
+ * If a refresh request is already in progress, it will return the Promise of this request.
306
+ * Otherwise, it will start a new refresh request and return its Promise.
307
+ *
308
+ * @returns {Promise<JwtToken<T, ExtraInfo>>} Promise of the refreshed token.
309
+ */
310
+ refreshToken() {
311
+ if (this.inflightPromise === void 0) {
312
+ this.inflightPromise = new Promise((resolve, reject) => {
313
+ this.resolver.getJwt().then(({ jwt, extraInfo }) => {
314
+ this.inflightPromise = void 0;
315
+ const token = this.jwtRepository.setToken(jwt, extraInfo);
316
+ resolve(token);
317
+ }).catch((reason) => {
318
+ this.inflightPromise = void 0;
319
+ reject(reason);
320
+ });
321
+ });
322
+ }
323
+ return this.inflightPromise;
324
+ }
325
+ /**
326
+ * Method to check if a token refresh is in progress.
327
+ *
328
+ * @returns {boolean} true if a token refresh is in progress, false otherwise.
329
+ */
330
+ get isRefreshingToken() {
331
+ return this.inflightPromise !== void 0;
332
+ }
333
+ }
334
+ export {
335
+ JwtManager,
336
+ JwtRepository,
337
+ JwtToken
338
+ };
339
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../node_modules/jwt-decode/build/jwt-decode.esm.js","../../utils/dist/index.js","../src/jwt-token.ts","../src/jwt-repository.ts","../src/jwt-manager.ts"],"sourcesContent":["function e(e){this.message=e}e.prototype=new Error,e.prototype.name=\"InvalidCharacterError\";var r=\"undefined\"!=typeof window&&window.atob&&window.atob.bind(window)||function(r){var t=String(r).replace(/=+$/,\"\");if(t.length%4==1)throw new e(\"'atob' failed: The string to be decoded is not correctly encoded.\");for(var n,o,a=0,i=0,c=\"\";o=t.charAt(i++);~o&&(n=a%4?64*n+o:o,a++%4)?c+=String.fromCharCode(255&n>>(-2*a&6)):0)o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".indexOf(o);return c};function t(e){var t=e.replace(/-/g,\"+\").replace(/_/g,\"/\");switch(t.length%4){case 0:break;case 2:t+=\"==\";break;case 3:t+=\"=\";break;default:throw\"Illegal base64url string!\"}try{return function(e){return decodeURIComponent(r(e).replace(/(.)/g,(function(e,r){var t=r.charCodeAt(0).toString(16).toUpperCase();return t.length<2&&(t=\"0\"+t),\"%\"+t})))}(t)}catch(e){return r(t)}}function n(e){this.message=e}function o(e,r){if(\"string\"!=typeof e)throw new n(\"Invalid token specified\");var o=!0===(r=r||{}).header?0:1;try{return JSON.parse(t(e.split(\".\")[o]))}catch(e){throw new n(\"Invalid token specified: \"+e.message)}}n.prototype=new Error,n.prototype.name=\"InvalidTokenError\";export default o;export{n as InvalidTokenError};\n//# sourceMappingURL=jwt-decode.esm.js.map\n","/*!\n * Copyright (c) 2022, Salesforce, Inc.,\n * All rights reserved.\n * For full license text, see the LICENSE.txt file\n */\nfunction bfs(start, predicate, getChildren) {\n const queue = [...start];\n const visited = /* @__PURE__ */ new Set([...start]);\n const matches2 = /* @__PURE__ */ new Set();\n while (queue.length) {\n const curr = queue.shift();\n if (predicate(curr)) {\n matches2.add(curr);\n }\n const children = getChildren(curr);\n for (const child of children) {\n if (!visited.has(child)) {\n visited.add(child);\n queue.push(child);\n }\n }\n }\n return matches2;\n}\nfunction lineFormatter(position, message, filePath) {\n return `${message} (${filePath}:${position.line}:${position.column})`;\n}\nclass DefaultFileParserLogger {\n constructor(services, filePath) {\n this.services = services;\n this.filePath = filePath;\n }\n trace(position, message) {\n this.services.logger.trace(this.format(position, message));\n }\n debug(position, message) {\n this.services.logger.debug(this.format(position, message));\n }\n info(position, message) {\n this.services.logger.info(this.format(position, message));\n }\n warn(position, message) {\n this.services.logger.warn(this.format(position, message));\n }\n error(position, message) {\n this.services.logger.error(this.format(position, message));\n }\n format(position, message) {\n return lineFormatter(position, message, this.filePath);\n }\n}\nfunction matches(test, s) {\n if (test === void 0) {\n return false;\n } else if (typeof test === \"string\") {\n return s === test;\n } else if (test instanceof RegExp) {\n return test.test(s);\n } else if (typeof test === \"function\") {\n return test(s);\n }\n return test.some((m) => matches(m, s));\n}\nfunction includes(incexc, s) {\n if (matches(incexc.exclude, s)) {\n return false;\n }\n if (matches(incexc.include, s)) {\n return true;\n }\n if (incexc.include) {\n return false;\n }\n return true;\n}\nconst { create, freeze, keys, entries } = Object;\nconst { hasOwnProperty } = Object.prototype;\nconst { isArray } = Array;\nconst { push, indexOf, slice } = Array.prototype;\nconst { stringify, parse } = JSON;\nconst WeakSetConstructor = WeakSet;\nconst LogLevelMap = {\n TRACE: 4,\n DEBUG: 3,\n INFO: 2,\n WARN: 1,\n ERROR: 0\n};\nclass ConsoleLogger {\n constructor(level = \"WARN\", printer = console.log, formatter = (level2, message) => `${level2}: ${message}`) {\n this.level = level;\n this.printer = printer;\n this.formatter = formatter;\n this.messages = [];\n }\n trace(message) {\n this.log(\"TRACE\", message);\n }\n debug(message) {\n this.log(\"DEBUG\", message);\n }\n info(message) {\n this.log(\"INFO\", message);\n }\n warn(message) {\n this.log(\"WARN\", message);\n }\n error(message) {\n this.log(\"ERROR\", message);\n }\n log(level, message) {\n if (LogLevelMap[level] > LogLevelMap[this.level]) {\n return;\n }\n this.printer(this.formatter(level, message));\n }\n}\nfunction loggerService(level, printer, formatter) {\n return new ConsoleLogger(level, printer, formatter);\n}\nclass Ok {\n constructor(value) {\n this.value = value;\n }\n isOk() {\n return true;\n }\n isErr() {\n return !this.isOk();\n }\n}\nclass Err {\n constructor(error) {\n this.error = error;\n }\n isOk() {\n return false;\n }\n isErr() {\n return !this.isOk();\n }\n}\nconst ok = (value) => new Ok(value);\nconst err = (err2) => new Err(err2);\nclass DataNotFoundError extends Error {\n constructor(message) {\n super(message);\n this.name = \"DataNotFoundError\";\n }\n}\nclass DataIncompleteError extends Error {\n constructor(message, partialData) {\n super(message);\n this.partialData = partialData;\n this.name = \"DataIncompleteError\";\n }\n}\nfunction isDataNotFoundError(error) {\n return error instanceof DataNotFoundError || error.name === \"DataNotFoundError\";\n}\nfunction isDataIncompleteError(error) {\n return error instanceof DataIncompleteError || error.name === \"DataIncompleteError\";\n}\nfunction isCacheHitOrError(value) {\n if (value.isErr() && (isDataIncompleteError(value.error) || isDataNotFoundError(value.error))) {\n return false;\n }\n return true;\n}\nfunction isCacheMiss(value) {\n return !isCacheHitOrError(value);\n}\nfunction isResult(value) {\n return value != null && typeof value === \"object\" && \"isOk\" in value && \"isErr\" in value && typeof value.isOk === \"function\" && typeof value.isErr === \"function\" && (value.isOk() === true && value.isErr() === false && \"value\" in value || value.isOk() === false && value.isErr() === true && \"error\" in value);\n}\nfunction setOverlaps(setA, setB) {\n for (const element of setA) {\n if (setB.has(element)) {\n return true;\n }\n }\n return false;\n}\nfunction setDifference(setA, setB) {\n const differenceSet = /* @__PURE__ */ new Set();\n for (const element of setA) {\n if (!setB.has(element)) {\n differenceSet.add(element);\n }\n }\n return differenceSet;\n}\nfunction addAllToSet(targetSet, sourceSet) {\n for (const element of sourceSet) {\n targetSet.add(element);\n }\n}\nconst toTypeScriptSafeIdentifier = (s) => s.length >= 1 ? s[0].replace(/[^$_\\p{ID_Start}]/u, \"_\") + s.slice(1).replace(/[^$\\u200c\\u200d\\p{ID_Continue}]/gu, \"_\") : \"\";\nfunction isSubscribable(obj) {\n return typeof obj === \"object\" && obj !== null && \"subscribe\" in obj && typeof obj.subscribe === \"function\" && \"refresh\" in obj && typeof obj.refresh === \"function\";\n}\nfunction isSubscribableResult(x) {\n if (!isResult(x)) {\n return false;\n }\n return isSubscribable(x.isOk() ? x.value : x.error);\n}\nfunction buildSubscribableResult(result, subscribe, refresh) {\n if (result.isOk()) {\n return ok({ data: result.value, subscribe, refresh });\n } else {\n return err({ failure: result.error, subscribe, refresh });\n }\n}\nfunction resolvedPromiseLike(result) {\n if (isPromiseLike(result)) {\n return result.then((nextResult) => nextResult);\n }\n return {\n then: (onFulfilled, _onRejected) => {\n try {\n return resolvedPromiseLike(onFulfilled(result));\n } catch (e) {\n if (onFulfilled === void 0) {\n return resolvedPromiseLike(result);\n }\n return rejectedPromiseLike(e);\n }\n }\n };\n}\nfunction rejectedPromiseLike(reason) {\n if (isPromiseLike(reason)) {\n return reason.then((nextResult) => nextResult);\n }\n return {\n then: (_onFulfilled, onRejected) => {\n if (typeof onRejected === \"function\") {\n try {\n return resolvedPromiseLike(onRejected(reason));\n } catch (e) {\n return rejectedPromiseLike(e);\n }\n }\n return rejectedPromiseLike(reason);\n }\n };\n}\nfunction isPromiseLike(x) {\n return typeof (x == null ? void 0 : x.then) === \"function\";\n}\nfunction racesync(values) {\n for (const value of values) {\n let settled = void 0;\n if (isPromiseLike(value)) {\n value.then(\n (_) => {\n settled = value;\n },\n (_) => {\n settled = value;\n }\n );\n } else {\n settled = resolvedPromiseLike(value);\n }\n if (settled !== void 0) {\n return settled;\n }\n }\n return Promise.race(values);\n}\nfunction withResolvers() {\n let resolve, reject;\n const promise = new Promise((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\nfunction deepEquals(x, y) {\n if (x === void 0) {\n return y === void 0;\n } else if (x === null) {\n return y === null;\n } else if (y === null) {\n return x === null;\n } else if (isArray(x)) {\n if (!isArray(y) || x.length !== y.length) {\n return false;\n }\n for (let i = 0; i < x.length; ++i) {\n if (!deepEquals(x[i], y[i])) {\n return false;\n }\n }\n return true;\n } else if (typeof x === \"object\") {\n if (typeof y !== \"object\") {\n return false;\n }\n const xkeys = Object.keys(x);\n const ykeys = Object.keys(y);\n if (xkeys.length !== ykeys.length) {\n return false;\n }\n for (let i = 0; i < xkeys.length; ++i) {\n const key = xkeys[i];\n if (!deepEquals(x[key], y[key])) {\n return false;\n }\n }\n return true;\n }\n return x === y;\n}\nfunction stableJSONStringify(node) {\n if (node && node.toJSON && typeof node.toJSON === \"function\") {\n node = node.toJSON();\n }\n if (node === void 0) {\n return;\n }\n if (typeof node === \"number\") {\n return isFinite(node) ? \"\" + node : \"null\";\n }\n if (typeof node !== \"object\") {\n return stringify(node);\n }\n let i;\n let out;\n if (isArray(node)) {\n out = \"[\";\n for (i = 0; i < node.length; i++) {\n if (i) {\n out += \",\";\n }\n out += stableJSONStringify(node[i]) || \"null\";\n }\n return out + \"]\";\n }\n if (node === null) {\n return \"null\";\n }\n const objKeys = keys(node).sort();\n out = \"\";\n for (i = 0; i < objKeys.length; i++) {\n const key = objKeys[i];\n const value = stableJSONStringify(node[key]);\n if (!value) {\n continue;\n }\n if (out) {\n out += \",\";\n }\n out += stringify(key) + \":\" + value;\n }\n return \"{\" + out + \"}\";\n}\nfunction toError(x) {\n if (x instanceof Error) {\n return x;\n }\n return new Error(typeof x === \"string\" ? x : JSON.stringify(x));\n}\nfunction deepCopy(x) {\n const stringified = stringify(x);\n return stringified ? parse(stringified) : void 0;\n}\nfunction readableStreamToAsyncIterable(stream) {\n if (stream.locked) {\n return err(new Error(\"ReadableStream is already locked\"));\n }\n if (Symbol.asyncIterator in stream) {\n return ok(stream);\n }\n const reader = stream.getReader();\n return ok({\n [Symbol.asyncIterator]: () => ({\n next: async () => {\n try {\n const result = await reader.read();\n if (result.done) {\n try {\n reader.releaseLock();\n } catch {\n }\n return { done: true, value: void 0 };\n }\n return {\n done: false,\n value: result.value\n };\n } catch (e) {\n try {\n reader.releaseLock();\n } catch {\n }\n throw e;\n }\n },\n return: async (value) => {\n try {\n await reader.cancel();\n } catch {\n }\n try {\n reader.releaseLock();\n } catch {\n }\n return { done: true, value };\n },\n throw: async (exception) => {\n try {\n await reader.cancel();\n } catch {\n }\n try {\n reader.releaseLock();\n } catch {\n }\n throw exception;\n }\n })\n });\n}\nfunction satisfies(provided, requested) {\n const providedN = provided.split(\".\").map((s) => parseInt(s));\n const requestedN = requested.split(\".\").map((s) => parseInt(s));\n return providedN[0] === requestedN[0] && providedN[1] >= requestedN[1];\n}\nfunction stringIsVersion(s) {\n const versionParts = s.split(\".\");\n return (versionParts.length === 2 || versionParts.length === 3) && versionParts.every((part) => part.match(/^\\d+$/));\n}\nvar HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {\n HttpStatusCode2[HttpStatusCode2[\"Ok\"] = 200] = \"Ok\";\n HttpStatusCode2[HttpStatusCode2[\"Created\"] = 201] = \"Created\";\n HttpStatusCode2[HttpStatusCode2[\"NoContent\"] = 204] = \"NoContent\";\n HttpStatusCode2[HttpStatusCode2[\"NotModified\"] = 304] = \"NotModified\";\n HttpStatusCode2[HttpStatusCode2[\"BadRequest\"] = 400] = \"BadRequest\";\n HttpStatusCode2[HttpStatusCode2[\"Unauthorized\"] = 401] = \"Unauthorized\";\n HttpStatusCode2[HttpStatusCode2[\"Forbidden\"] = 403] = \"Forbidden\";\n HttpStatusCode2[HttpStatusCode2[\"NotFound\"] = 404] = \"NotFound\";\n HttpStatusCode2[HttpStatusCode2[\"ServerError\"] = 500] = \"ServerError\";\n HttpStatusCode2[HttpStatusCode2[\"GatewayTimeout\"] = 504] = \"GatewayTimeout\";\n return HttpStatusCode2;\n})(HttpStatusCode || {});\nfunction getFetchResponseFromAuraError(err2) {\n if (err2.data !== void 0 && err2.data.statusCode !== void 0) {\n let data = {};\n data = err2.data;\n if (err2.id !== void 0) {\n data.id = err2.id;\n }\n return new FetchResponse(data.statusCode, data);\n }\n return new FetchResponse(500, {\n error: err2.message\n });\n}\nasync function coerceResponseToFetchResponse(response) {\n const { status } = response;\n const responseHeaders = {};\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n let responseBody = null;\n if (status !== 204) {\n const contentType = responseHeaders[\"content-type\"];\n responseBody = contentType && contentType.startsWith(\"application/json\") ? await response.json() : await response.text();\n }\n return new FetchResponse(status, responseBody, responseHeaders);\n}\nfunction getStatusText(status) {\n switch (status) {\n case 200:\n return \"OK\";\n case 201:\n return \"Created\";\n case 304:\n return \"Not Modified\";\n case 400:\n return \"Bad Request\";\n case 404:\n return \"Not Found\";\n case 500:\n return \"Server Error\";\n default:\n return `Unexpected HTTP Status Code: ${status}`;\n }\n}\nclass FetchResponse extends Error {\n constructor(status, body, headers) {\n super();\n this.status = status;\n this.body = body;\n this.headers = headers || {};\n this.ok = status >= 200 && this.status <= 299;\n this.statusText = getStatusText(status);\n }\n}\nconst deeplyFrozen = new WeakSetConstructor();\nfunction deepFreeze(value) {\n if (typeof value !== \"object\" || value === null || deeplyFrozen.has(value)) {\n return;\n }\n deeplyFrozen.add(value);\n if (isArray(value)) {\n for (let i = 0, len = value.length; i < len; i += 1) {\n deepFreeze(value[i]);\n }\n } else {\n const keys$1 = keys(value);\n for (let i = 0, len = keys$1.length; i < len; i += 1) {\n deepFreeze(value[keys$1[i]]);\n }\n }\n freeze(value);\n}\nfunction isScalar(value) {\n return typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\" || value === null || value === void 0;\n}\nfunction isScalarObject(value) {\n return Object.values(value).every((value2) => isScalar(value2));\n}\nfunction isScalarArray(value) {\n return value.every((item) => isScalar(item));\n}\nfunction encodeQueryParam(paramName, value, explode) {\n switch (typeof value) {\n case \"string\":\n return [`${paramName}=${encodeURIComponent(value)}`];\n case \"number\":\n case \"boolean\":\n return [`${paramName}=${value}`];\n case \"object\":\n if (value === null) {\n return [];\n }\n if (isArray(value)) {\n if (!isScalarArray(value)) {\n throw new Error(`Unsupported non-scalar array type for ${paramName}`);\n }\n if (explode) {\n return value.map(\n (item) => `${paramName}=${item ? encodeURIComponent(item) : item}`\n );\n }\n return [\n `${paramName}=${value.map((item) => item ? encodeURIComponent(item) : item).join(\",\")}`\n ];\n }\n if (!isScalarObject(value)) {\n throw new Error(`Unsupported non-scalar object type for ${paramName}`);\n }\n if (explode) {\n return entries(value).map(\n ([key, value2]) => `${key}=${value2 ? encodeURIComponent(value2) : value2}`\n );\n }\n return [\n `${paramName}=${entries(value).flat().map((item) => item ? encodeURIComponent(item) : item).join(\",\")}`\n ];\n default:\n return [];\n }\n}\nclass InternalError extends Error {\n constructor(data) {\n super();\n this.data = data;\n this.type = \"internal\";\n }\n}\nclass UserVisibleError extends Error {\n constructor(data) {\n super();\n this.data = data;\n this.type = \"user-visible\";\n }\n}\nfunction applyDecorators(baseCommand, decorators, options) {\n if (!decorators || decorators.length === 0) {\n return baseCommand;\n }\n return decorators.reduce((command, decorator) => decorator(command, options), baseCommand);\n}\nexport {\n isArray as ArrayIsArray,\n indexOf as ArrayPrototypeIndexOf,\n push as ArrayPrototypePush,\n slice as ArrayPrototypeSlice,\n ConsoleLogger,\n DataIncompleteError,\n DataNotFoundError,\n DefaultFileParserLogger,\n Err,\n FetchResponse,\n HttpStatusCode,\n InternalError,\n parse as JSONParse,\n stringify as JSONStringify,\n LogLevelMap,\n create as ObjectCreate,\n entries as ObjectEntries,\n freeze as ObjectFreeze,\n keys as ObjectKeys,\n hasOwnProperty as ObjectPrototypeHasOwnProperty,\n Ok,\n UserVisibleError,\n WeakSetConstructor,\n addAllToSet,\n applyDecorators,\n bfs,\n buildSubscribableResult,\n coerceResponseToFetchResponse,\n deepCopy,\n deepEquals,\n deepFreeze,\n encodeQueryParam,\n err,\n getFetchResponseFromAuraError,\n includes,\n isCacheHitOrError,\n isCacheMiss,\n isDataIncompleteError,\n isDataNotFoundError,\n isPromiseLike,\n isResult,\n isSubscribable,\n isSubscribableResult,\n lineFormatter,\n loggerService,\n ok,\n racesync,\n readableStreamToAsyncIterable,\n rejectedPromiseLike,\n resolvedPromiseLike,\n satisfies,\n setDifference,\n setOverlaps,\n stableJSONStringify,\n stringIsVersion,\n toError,\n toTypeScriptSafeIdentifier,\n withResolvers\n};\n//# sourceMappingURL=index.js.map\n","import type { JwtPayload } from 'jwt-decode';\n\n/**\n * Represents a decoded JWT payload with a non-nullable 'exp' field and any additional payload T.\n */\nexport type JwtTokenInfo<T = unknown> = JwtPayload & { exp: NonNullable<JwtPayload['exp']> } & T;\n\n/**\n * Represents a JWT token with its decoded info and optional extra info.\n *\n * @typeparam T - Type of the additional payload in the JWT.\n * @typeparam ExtraInfo - Type of the additional information.\n */\nexport class JwtToken<T = unknown, ExtraInfo = undefined> {\n /**\n * Create a new JwtToken.\n *\n * @param _token - The JWT string.\n * @param _decodedInfo - The decoded information from the JWT.\n * @param _extraInfo - Any additional information associated with the JWT.\n */\n constructor(\n private _token: string,\n private _decodedInfo: JwtTokenInfo<T>,\n private _extraInfo?: ExtraInfo\n ) {}\n\n /**\n * Get the JWT string.\n *\n * @returns The JWT string.\n */\n public get token() {\n return this._token;\n }\n\n /**\n * Get the additional information associated with the JWT.\n *\n * @returns The additional information.\n */\n public get extraInfo() {\n return this._extraInfo;\n }\n\n /**\n * Get the decoded information from the JWT.\n *\n * @returns The decoded information.\n */\n public get decodedInfo() {\n return this._decodedInfo;\n }\n\n /**\n * Get the remaining time in seconds until the JWT expires.\n *\n * @returns The remaining time in seconds.\n */\n public get tokenRemainingSeconds(): number {\n return this.decodedInfo.exp - Date.now() / 1000;\n }\n\n /**\n * Check if the JWT is expired.\n *\n * @returns True if the JWT is expired, false otherwise.\n */\n public get isExpired(): boolean {\n return this.tokenRemainingSeconds <= 0;\n }\n}\n","import jwt_decode from 'jwt-decode';\nimport { loggerService } from '@conduit-client/utils';\nimport { JwtToken } from './jwt-token';\nimport type { LoggerService } from '@conduit-client/utils';\nimport type { JwtTokenInfo } from './jwt-token';\n\n/**\n * Default logger if none is provided. Is overwritten in non-production environments.\n */\nlet defaultLogger: LoggerService = {\n trace: () => {},\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\nif (process.env.NODE_ENV !== 'production') {\n defaultLogger = loggerService();\n}\n\n/**\n * Decodes JWT token information and provides a default expiry if none is present.\n *\n * @param token - JWT token as a string.\n * @param defaultTokenTTLInSeconds - Default expiry time in seconds if \"exp\" claim is not present in token.\n * @param logger - Logger for logging warnings and errors.\n *\n * @returns An object of decoded JWT token information.\n */\nfunction computeDecodedInfo<T>(\n token: string,\n defaultTokenTTLInSeconds: number,\n logger: LoggerService\n): JwtTokenInfo<T> {\n const decodedInfo = jwt_decode<JwtTokenInfo<T>>(token);\n\n if (decodedInfo.exp === undefined) {\n logger.warn(`\"exp\" claim is not present in the provided token.`);\n decodedInfo.exp = Date.now() / 1000 + defaultTokenTTLInSeconds;\n }\n\n return decodedInfo;\n}\n\n/**\n * A repository for JWT tokens.\n */\nexport class JwtRepository<T = unknown, ExtraInfo = undefined> {\n private _token?: JwtToken<T, ExtraInfo>;\n private timeoutHandler?: ReturnType<typeof setTimeout>;\n private observers: Array<(token: JwtToken<T, ExtraInfo>) => void> = [];\n\n /**\n * @param limitInSeconds - Time in seconds before the token's expiry to notify observers.\n * @param defaultTokenTTLInSeconds - Default token expiry time in seconds if \"exp\" claim is not present in token.\n * @param logger - Logger for logging warnings and errors.\n */\n constructor(\n private limitInSeconds: number = 5,\n private defaultTokenTTLInSeconds = 120,\n private logger: LoggerService = defaultLogger\n ) {}\n\n /**\n * Get the current token.\n */\n public get token() {\n return this._token;\n }\n\n /**\n * Set the current token.\n *\n * @param token - JWT token as a string.\n * @param extraInfo - Optional extra information.\n */\n public setToken(token: string, extraInfo?: ExtraInfo): JwtToken<T, ExtraInfo> {\n const decodedInfo = computeDecodedInfo<T>(\n token,\n this.defaultTokenTTLInSeconds,\n this.logger\n );\n this._token = new JwtToken<T, ExtraInfo>(token, decodedInfo, extraInfo);\n\n this.observeTokenExpiration();\n\n return this._token;\n }\n\n /**\n * Remove the current token.\n */\n public removeToken(): void {\n this._token = undefined;\n this.clearTimeoutHandler();\n }\n\n /**\n * Subscribe to the token nearing its expiration.\n *\n * @param cb - Callback function to execute when token is nearing expiration.\n */\n public subscribeToTokenNearExpiration(cb: (token: JwtToken<T, ExtraInfo>) => void): () => void {\n this.observers.push(cb);\n this.observeTokenExpiration();\n\n return () => {\n this.observers = this.observers.filter((observer) => observer !== cb);\n };\n }\n\n /**\n * Clear the timeout handler.\n */\n private clearTimeoutHandler(): void {\n if (this.timeoutHandler !== undefined) {\n clearTimeout(this.timeoutHandler);\n }\n }\n\n /**\n * Observe and handle token expiration.\n */\n private observeTokenExpiration(): void {\n this.clearTimeoutHandler();\n if (this.observers.length === 0 || this.token === undefined) {\n return;\n }\n\n this.timeoutHandler = setTimeout(\n () => this.notifyTokenIsExpiring(),\n this.computeTimeoutTimeInMs()\n );\n }\n\n /**\n * Compute the timeout time in milliseconds.\n */\n private computeTimeoutTimeInMs() {\n const remainingSeconds = this.token!.tokenRemainingSeconds;\n\n let timeoutTimeInSeconds = remainingSeconds - this.limitInSeconds;\n\n return timeoutTimeInSeconds < 0 ? 0 : timeoutTimeInSeconds * 1000;\n }\n\n /**\n * Notify all observers that the token is expiring.\n */\n private notifyTokenIsExpiring() {\n this.observers.forEach((cb) => {\n try {\n cb.call(undefined, this.token!);\n } catch (e) {\n this.logger.error((e as Error).message);\n }\n });\n }\n}\n","import type { JwtRepository } from './jwt-repository';\nimport type { JwtToken } from './jwt-token';\n\n/**\n * JwtResolver type. It is used to define the structure for JWT resolver instances.\n * JwtResolver contains a method getJwt that should return a Promise with a JWT and optionally extra information.\n *\n * @template ExtraInfo The type of the optional extra information returned by the getJwt method. Defaults to undefined.\n * @property {() => Promise<{ jwt: string; extraInfo: ExtraInfo }>} getJwt Method for getting a JWT.\n */\nexport type JwtResolver<ExtraInfo = undefined> = {\n getJwt(): Promise<{ jwt: string; extraInfo: ExtraInfo }>;\n};\n\n/**\n * JwtManagerOptions bag\n *\n * keepTokenUpdated: indicates whether the token should be updated each time it nears expiration\n * @property {boolean}\n */\nexport type JwtManagerOptions = {\n keepTokenUpdated?: boolean;\n};\n\n/**\n * JwtManager class.\n * It provides methods for managing JWT (Json Web Token), such as retrieving and refreshing.\n *\n * @template T The data type the JwtToken carries. Default to unknown.\n * @template ExtraInfo The type of the optional extra information returned by the getJwt method. Defaults to undefined.\n * @property {JwtRepository<T, ExtraInfo>} jwtRepository JwtRepository instance used for token management.\n * @property {JwtResolver<ExtraInfo>} resolver JwtResolver instance used for token retrieval.\n */\nexport class JwtManager<T = unknown, ExtraInfo = undefined> {\n private inflightPromise?: Promise<JwtToken<T, ExtraInfo>>;\n\n /**\n * Constructor for JwtManager class.\n *\n * @param {JwtRepository<T, ExtraInfo>} jwtRepository JwtRepository instance used for token management.\n * @param {JwtResolver<ExtraInfo>} resolver JwtResolver instance used for token retrieval.\n * @param {JwtManagerOptions} options JwtManagerOptions bag to customize behavior.\n */\n constructor(\n private jwtRepository: JwtRepository<T, ExtraInfo>,\n private resolver: JwtResolver<ExtraInfo>,\n options?: JwtManagerOptions\n ) {\n if (options?.keepTokenUpdated) {\n jwtRepository.subscribeToTokenNearExpiration(() => this.refreshToken());\n }\n }\n\n /**\n * Method to get a JWT token.\n * If there's a token request in progress, it will return the Promise of this request.\n * If the current token is undefined or expired, it will initiate a token refresh.\n * Otherwise, it will return the current token.\n *\n * @returns {JwtToken<T, ExtraInfo> | Promise<JwtToken<T, ExtraInfo>>} The current token or the Promise of a token request.\n */\n getJwt(): JwtToken<T, ExtraInfo> | Promise<JwtToken<T, ExtraInfo>> {\n if (this.inflightPromise) {\n return this.inflightPromise;\n }\n\n const token = this.jwtRepository.token;\n\n if (token === undefined || token.isExpired) {\n return this.refreshToken();\n }\n\n return token;\n }\n\n /**\n * Method to refresh a JWT token.\n * If a refresh request is already in progress, it will return the Promise of this request.\n * Otherwise, it will start a new refresh request and return its Promise.\n *\n * @returns {Promise<JwtToken<T, ExtraInfo>>} Promise of the refreshed token.\n */\n refreshToken(): Promise<JwtToken<T, ExtraInfo>> {\n if (this.inflightPromise === undefined) {\n this.inflightPromise = new Promise((resolve, reject) => {\n this.resolver\n .getJwt()\n .then(({ jwt, extraInfo }) => {\n this.inflightPromise = undefined;\n const token = this.jwtRepository.setToken(jwt, extraInfo);\n resolve(token);\n })\n .catch((reason) => {\n this.inflightPromise = undefined;\n reject(reason);\n });\n });\n }\n\n return this.inflightPromise;\n }\n\n /**\n * Method to check if a token refresh is in progress.\n *\n * @returns {boolean} true if a token refresh is in progress, false otherwise.\n */\n get isRefreshingToken() {\n return this.inflightPromise !== undefined;\n }\n}\n"],"names":["e","r","t","n","o","jwt_decode"],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export { JwtRepository } from './jwt-repository';
2
+ export { JwtManager } from './jwt-manager';
3
+ export { JwtToken } from './jwt-token';
4
+ export type { JwtTokenInfo } from './jwt-token';
5
+ export type { JwtResolver } from './jwt-manager';
@@ -0,0 +1,69 @@
1
+ import type { JwtRepository } from './jwt-repository';
2
+ import type { JwtToken } from './jwt-token';
3
+ /**
4
+ * JwtResolver type. It is used to define the structure for JWT resolver instances.
5
+ * JwtResolver contains a method getJwt that should return a Promise with a JWT and optionally extra information.
6
+ *
7
+ * @template ExtraInfo The type of the optional extra information returned by the getJwt method. Defaults to undefined.
8
+ * @property {() => Promise<{ jwt: string; extraInfo: ExtraInfo }>} getJwt Method for getting a JWT.
9
+ */
10
+ export type JwtResolver<ExtraInfo = undefined> = {
11
+ getJwt(): Promise<{
12
+ jwt: string;
13
+ extraInfo: ExtraInfo;
14
+ }>;
15
+ };
16
+ /**
17
+ * JwtManagerOptions bag
18
+ *
19
+ * keepTokenUpdated: indicates whether the token should be updated each time it nears expiration
20
+ * @property {boolean}
21
+ */
22
+ export type JwtManagerOptions = {
23
+ keepTokenUpdated?: boolean;
24
+ };
25
+ /**
26
+ * JwtManager class.
27
+ * It provides methods for managing JWT (Json Web Token), such as retrieving and refreshing.
28
+ *
29
+ * @template T The data type the JwtToken carries. Default to unknown.
30
+ * @template ExtraInfo The type of the optional extra information returned by the getJwt method. Defaults to undefined.
31
+ * @property {JwtRepository<T, ExtraInfo>} jwtRepository JwtRepository instance used for token management.
32
+ * @property {JwtResolver<ExtraInfo>} resolver JwtResolver instance used for token retrieval.
33
+ */
34
+ export declare class JwtManager<T = unknown, ExtraInfo = undefined> {
35
+ private jwtRepository;
36
+ private resolver;
37
+ private inflightPromise?;
38
+ /**
39
+ * Constructor for JwtManager class.
40
+ *
41
+ * @param {JwtRepository<T, ExtraInfo>} jwtRepository JwtRepository instance used for token management.
42
+ * @param {JwtResolver<ExtraInfo>} resolver JwtResolver instance used for token retrieval.
43
+ * @param {JwtManagerOptions} options JwtManagerOptions bag to customize behavior.
44
+ */
45
+ constructor(jwtRepository: JwtRepository<T, ExtraInfo>, resolver: JwtResolver<ExtraInfo>, options?: JwtManagerOptions);
46
+ /**
47
+ * Method to get a JWT token.
48
+ * If there's a token request in progress, it will return the Promise of this request.
49
+ * If the current token is undefined or expired, it will initiate a token refresh.
50
+ * Otherwise, it will return the current token.
51
+ *
52
+ * @returns {JwtToken<T, ExtraInfo> | Promise<JwtToken<T, ExtraInfo>>} The current token or the Promise of a token request.
53
+ */
54
+ getJwt(): JwtToken<T, ExtraInfo> | Promise<JwtToken<T, ExtraInfo>>;
55
+ /**
56
+ * Method to refresh a JWT token.
57
+ * If a refresh request is already in progress, it will return the Promise of this request.
58
+ * Otherwise, it will start a new refresh request and return its Promise.
59
+ *
60
+ * @returns {Promise<JwtToken<T, ExtraInfo>>} Promise of the refreshed token.
61
+ */
62
+ refreshToken(): Promise<JwtToken<T, ExtraInfo>>;
63
+ /**
64
+ * Method to check if a token refresh is in progress.
65
+ *
66
+ * @returns {boolean} true if a token refresh is in progress, false otherwise.
67
+ */
68
+ get isRefreshingToken(): boolean;
69
+ }
@@ -0,0 +1,56 @@
1
+ import { JwtToken } from './jwt-token';
2
+ import type { LoggerService } from '@conduit-client/utils';
3
+ /**
4
+ * A repository for JWT tokens.
5
+ */
6
+ export declare class JwtRepository<T = unknown, ExtraInfo = undefined> {
7
+ private limitInSeconds;
8
+ private defaultTokenTTLInSeconds;
9
+ private logger;
10
+ private _token?;
11
+ private timeoutHandler?;
12
+ private observers;
13
+ /**
14
+ * @param limitInSeconds - Time in seconds before the token's expiry to notify observers.
15
+ * @param defaultTokenTTLInSeconds - Default token expiry time in seconds if "exp" claim is not present in token.
16
+ * @param logger - Logger for logging warnings and errors.
17
+ */
18
+ constructor(limitInSeconds?: number, defaultTokenTTLInSeconds?: number, logger?: LoggerService);
19
+ /**
20
+ * Get the current token.
21
+ */
22
+ get token(): JwtToken<T, ExtraInfo> | undefined;
23
+ /**
24
+ * Set the current token.
25
+ *
26
+ * @param token - JWT token as a string.
27
+ * @param extraInfo - Optional extra information.
28
+ */
29
+ setToken(token: string, extraInfo?: ExtraInfo): JwtToken<T, ExtraInfo>;
30
+ /**
31
+ * Remove the current token.
32
+ */
33
+ removeToken(): void;
34
+ /**
35
+ * Subscribe to the token nearing its expiration.
36
+ *
37
+ * @param cb - Callback function to execute when token is nearing expiration.
38
+ */
39
+ subscribeToTokenNearExpiration(cb: (token: JwtToken<T, ExtraInfo>) => void): () => void;
40
+ /**
41
+ * Clear the timeout handler.
42
+ */
43
+ private clearTimeoutHandler;
44
+ /**
45
+ * Observe and handle token expiration.
46
+ */
47
+ private observeTokenExpiration;
48
+ /**
49
+ * Compute the timeout time in milliseconds.
50
+ */
51
+ private computeTimeoutTimeInMs;
52
+ /**
53
+ * Notify all observers that the token is expiring.
54
+ */
55
+ private notifyTokenIsExpiring;
56
+ }
@@ -0,0 +1,56 @@
1
+ import type { JwtPayload } from 'jwt-decode';
2
+ /**
3
+ * Represents a decoded JWT payload with a non-nullable 'exp' field and any additional payload T.
4
+ */
5
+ export type JwtTokenInfo<T = unknown> = JwtPayload & {
6
+ exp: NonNullable<JwtPayload['exp']>;
7
+ } & T;
8
+ /**
9
+ * Represents a JWT token with its decoded info and optional extra info.
10
+ *
11
+ * @typeparam T - Type of the additional payload in the JWT.
12
+ * @typeparam ExtraInfo - Type of the additional information.
13
+ */
14
+ export declare class JwtToken<T = unknown, ExtraInfo = undefined> {
15
+ private _token;
16
+ private _decodedInfo;
17
+ private _extraInfo?;
18
+ /**
19
+ * Create a new JwtToken.
20
+ *
21
+ * @param _token - The JWT string.
22
+ * @param _decodedInfo - The decoded information from the JWT.
23
+ * @param _extraInfo - Any additional information associated with the JWT.
24
+ */
25
+ constructor(_token: string, _decodedInfo: JwtTokenInfo<T>, _extraInfo?: ExtraInfo | undefined);
26
+ /**
27
+ * Get the JWT string.
28
+ *
29
+ * @returns The JWT string.
30
+ */
31
+ get token(): string;
32
+ /**
33
+ * Get the additional information associated with the JWT.
34
+ *
35
+ * @returns The additional information.
36
+ */
37
+ get extraInfo(): ExtraInfo | undefined;
38
+ /**
39
+ * Get the decoded information from the JWT.
40
+ *
41
+ * @returns The decoded information.
42
+ */
43
+ get decodedInfo(): JwtTokenInfo<T>;
44
+ /**
45
+ * Get the remaining time in seconds until the JWT expires.
46
+ *
47
+ * @returns The remaining time in seconds.
48
+ */
49
+ get tokenRemainingSeconds(): number;
50
+ /**
51
+ * Check if the JWT is expired.
52
+ *
53
+ * @returns True if the JWT is expired, false otherwise.
54
+ */
55
+ get isExpired(): boolean;
56
+ }
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@conduit-client/jwt-manager",
3
+ "version": "5.67.0-dev1",
4
+ "description": "Luvio Next generic JWT manager",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/salesforce-experience-platform-emu/luvio-next.git",
9
+ "directory": "packages/@conduit-client/jwt-manager"
10
+ },
11
+ "license": "SEE LICENSE IN LICENSE.txt",
12
+ "main": "dist/index.js",
13
+ "types": "dist/types/index.d.ts",
14
+ "files": [
15
+ "dist/"
16
+ ],
17
+ "scripts": {
18
+ "build": "vite build && tsc --build --emitDeclarationOnly",
19
+ "clean": "rm -rf dist",
20
+ "test": "vitest run",
21
+ "test:size": "size-limit",
22
+ "watch": "npm run build --watch"
23
+ },
24
+ "dependencies": {
25
+ "jwt-decode": "~3.1.2"
26
+ },
27
+ "devDependencies": {
28
+ "@conduit-client/utils": "5.67.0-dev1"
29
+ },
30
+ "size-limit": [
31
+ {
32
+ "path": "./dist/index.js",
33
+ "limit": "3 kB"
34
+ }
35
+ ]
36
+ }