astro-tokenkit 1.0.20 → 1.0.21
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/auth/manager.js +44 -16
- package/dist/client/client.js +9 -3
- package/dist/index.cjs +59 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/index.js +59 -26
- package/dist/index.js.map +1 -1
- package/dist/integration.js +1 -1
- package/dist/middleware.cjs +50 -22
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.js +50 -22
- package/dist/middleware.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/utils/logger.d.ts +2 -2
- package/dist/utils/logger.js +4 -4
- package/package.json +1 -1
package/dist/auth/manager.js
CHANGED
|
@@ -127,11 +127,27 @@ export class TokenManager {
|
|
|
127
127
|
*/
|
|
128
128
|
refresh(ctx, refreshToken, options, headers) {
|
|
129
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
logger.debug('[TokenKit] Starting token refresh', !!this.config.debug);
|
|
130
131
|
try {
|
|
131
|
-
|
|
132
|
+
const bundle = yield this.performRefresh(ctx, refreshToken, options, headers);
|
|
133
|
+
if (bundle) {
|
|
134
|
+
if (this.config.onRefresh) {
|
|
135
|
+
yield this.config.onRefresh(bundle, ctx);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
logger.debug('[TokenKit] Token refresh returned no bundle (invalid or expired)', !!this.config.debug);
|
|
140
|
+
if (this.config.onRefreshError) {
|
|
141
|
+
yield this.config.onRefreshError(new AuthError('Refresh token invalid or expired', 401), ctx);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return bundle;
|
|
132
145
|
}
|
|
133
146
|
catch (error) {
|
|
134
|
-
|
|
147
|
+
logger.debug(`[TokenKit] Token refresh failed: ${error.message}`, !!this.config.debug);
|
|
148
|
+
if (this.config.onRefreshError) {
|
|
149
|
+
yield this.config.onRefreshError(error, ctx);
|
|
150
|
+
}
|
|
135
151
|
throw error;
|
|
136
152
|
}
|
|
137
153
|
});
|
|
@@ -210,14 +226,19 @@ export class TokenManager {
|
|
|
210
226
|
const tokens = retrieveTokens(ctx, this.config.cookies);
|
|
211
227
|
// No tokens
|
|
212
228
|
if (!tokens.accessToken || !tokens.refreshToken || !tokens.expiresAt) {
|
|
229
|
+
logger.debug('[TokenKit] No valid session found, refresh impossible', !!this.config.debug);
|
|
213
230
|
return null;
|
|
214
231
|
}
|
|
215
232
|
// Token expired or force refresh
|
|
216
|
-
|
|
233
|
+
const expired = isExpired(tokens.expiresAt, now, this.config.policy);
|
|
234
|
+
if (force || expired) {
|
|
235
|
+
logger.debug(`[TokenKit] Token ${force ? 'force refresh' : 'expired'}, refreshing...`, !!this.config.debug);
|
|
217
236
|
const flightKey = this.createFlightKey(tokens.refreshToken);
|
|
218
237
|
const bundle = yield this.singleFlight.execute(flightKey, () => this.refresh(ctx, tokens.refreshToken, options, headers));
|
|
219
|
-
if (!bundle)
|
|
238
|
+
if (!bundle) {
|
|
239
|
+
logger.debug('[TokenKit] Refresh returned no bundle, session lost', !!this.config.debug);
|
|
220
240
|
return null;
|
|
241
|
+
}
|
|
221
242
|
// Ensure tokens are stored in the current context (in case of shared flight)
|
|
222
243
|
storeTokens(ctx, bundle, this.config.cookies);
|
|
223
244
|
return {
|
|
@@ -229,19 +250,26 @@ export class TokenManager {
|
|
|
229
250
|
}
|
|
230
251
|
// Proactive refresh
|
|
231
252
|
if (shouldRefresh(tokens.expiresAt, now, tokens.lastRefreshAt, this.config.policy)) {
|
|
253
|
+
logger.debug('[TokenKit] Token near expiration, performing proactive refresh', !!this.config.debug);
|
|
232
254
|
const flightKey = this.createFlightKey(tokens.refreshToken);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
255
|
+
try {
|
|
256
|
+
const bundle = yield this.singleFlight.execute(flightKey, () => this.refresh(ctx, tokens.refreshToken, options, headers));
|
|
257
|
+
if (bundle) {
|
|
258
|
+
logger.debug('[TokenKit] Proactive refresh successful', !!this.config.debug);
|
|
259
|
+
// Ensure tokens are stored in the current context (in case of shared flight)
|
|
260
|
+
storeTokens(ctx, bundle, this.config.cookies);
|
|
261
|
+
return {
|
|
262
|
+
accessToken: bundle.accessToken,
|
|
263
|
+
expiresAt: bundle.accessExpiresAt,
|
|
264
|
+
tokenType: bundle.tokenType,
|
|
265
|
+
payload: (_d = (_c = bundle.sessionPayload) !== null && _c !== void 0 ? _c : parseJWTPayload(bundle.accessToken)) !== null && _d !== void 0 ? _d : undefined,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
logger.debug(`[TokenKit] Proactive refresh failed: ${error.message}. Continuing with current token.`, !!this.config.debug);
|
|
243
271
|
}
|
|
244
|
-
// Refresh failed, check if tokens still exist
|
|
272
|
+
// Refresh failed or returned no bundle, check if tokens still exist
|
|
245
273
|
const currentTokens = retrieveTokens(ctx, this.config.cookies);
|
|
246
274
|
if (!currentTokens.accessToken) {
|
|
247
275
|
return null;
|
|
@@ -283,7 +311,7 @@ export class TokenManager {
|
|
|
283
311
|
}
|
|
284
312
|
catch (error) {
|
|
285
313
|
// Ignore logout endpoint errors
|
|
286
|
-
logger.debug('[TokenKit] Logout endpoint failed:', error);
|
|
314
|
+
logger.debug('[TokenKit] Logout endpoint failed:', !!this.config.debug, error);
|
|
287
315
|
}
|
|
288
316
|
finally {
|
|
289
317
|
clearTimeout(timeoutId);
|
package/dist/client/client.js
CHANGED
|
@@ -15,6 +15,7 @@ import { calculateDelay, shouldRetry, sleep } from '../utils/retry';
|
|
|
15
15
|
import { getConfig, getTokenManager } from '../config';
|
|
16
16
|
import { createMiddleware } from '../middleware';
|
|
17
17
|
import { safeFetch } from '../utils/fetch';
|
|
18
|
+
import { logger } from '../utils/logger';
|
|
18
19
|
/**
|
|
19
20
|
* API Client
|
|
20
21
|
*/
|
|
@@ -38,7 +39,7 @@ export class APIClient {
|
|
|
38
39
|
* Get token manager
|
|
39
40
|
*/
|
|
40
41
|
get tokenManager() {
|
|
41
|
-
var _a, _b;
|
|
42
|
+
var _a, _b, _c;
|
|
42
43
|
const config = this.config;
|
|
43
44
|
if (!config.auth)
|
|
44
45
|
return undefined;
|
|
@@ -54,8 +55,8 @@ export class APIClient {
|
|
|
54
55
|
if (!this._localTokenManager ||
|
|
55
56
|
this._lastUsedAuth !== config.auth ||
|
|
56
57
|
this._lastUsedBaseURL !== config.baseURL) {
|
|
57
|
-
// Merge client-level fetch and
|
|
58
|
-
const authConfig = Object.assign(Object.assign({}, config.auth), { fetch: (_a = config.auth.fetch) !== null && _a !== void 0 ? _a : config.fetch, dangerouslyIgnoreCertificateErrors: (_b = config.auth.dangerouslyIgnoreCertificateErrors) !== null && _b !== void 0 ? _b : config.dangerouslyIgnoreCertificateErrors });
|
|
58
|
+
// Merge client-level fetch, SSL and debug settings into auth config
|
|
59
|
+
const authConfig = Object.assign(Object.assign({}, config.auth), { fetch: (_a = config.auth.fetch) !== null && _a !== void 0 ? _a : config.fetch, dangerouslyIgnoreCertificateErrors: (_b = config.auth.dangerouslyIgnoreCertificateErrors) !== null && _b !== void 0 ? _b : config.dangerouslyIgnoreCertificateErrors, debug: (_c = config.auth.debug) !== null && _c !== void 0 ? _c : config.debug });
|
|
59
60
|
this._localTokenManager = new TokenManager(authConfig, config.baseURL);
|
|
60
61
|
this._lastUsedAuth = config.auth;
|
|
61
62
|
this._lastUsedBaseURL = config.baseURL;
|
|
@@ -144,8 +145,10 @@ export class APIClient {
|
|
|
144
145
|
return __awaiter(this, void 0, void 0, function* () {
|
|
145
146
|
var _a, _b, _c, _d, _e;
|
|
146
147
|
const method = config.method.toUpperCase();
|
|
148
|
+
const debug = this.config.debug;
|
|
147
149
|
// Ensure valid session (if auth is enabled)
|
|
148
150
|
if (this.tokenManager && !config.skipAuth) {
|
|
151
|
+
logger.debug(`[TokenKit] Ensuring valid session for ${method} ${config.url}`, !!debug);
|
|
149
152
|
yield this.tokenManager.ensure(ctx, config.auth, config.headers);
|
|
150
153
|
}
|
|
151
154
|
// Build full URL
|
|
@@ -183,12 +186,15 @@ export class APIClient {
|
|
|
183
186
|
clearTimeout(timeoutId);
|
|
184
187
|
// Handle 401 (try refresh and retry once)
|
|
185
188
|
if (response.status === 401 && this.tokenManager && !config.skipAuth && attempt === 1) {
|
|
189
|
+
logger.debug('[TokenKit] Received 401, attempting force refresh and retry...', !!debug);
|
|
186
190
|
// Clear and try fresh session (force refresh)
|
|
187
191
|
const session = yield this.tokenManager.ensure(ctx, config.auth, config.headers, true);
|
|
188
192
|
if (session) {
|
|
193
|
+
logger.debug('[TokenKit] Force refresh successful, retrying request...', !!debug);
|
|
189
194
|
// Retry with new token
|
|
190
195
|
return this.executeRequest(config, ctx, attempt + 1);
|
|
191
196
|
}
|
|
197
|
+
logger.debug('[TokenKit] Force refresh failed or returned no session', !!debug);
|
|
192
198
|
}
|
|
193
199
|
// Parse response
|
|
194
200
|
const apiResponse = yield this.parseResponse(response, fullURL);
|
package/dist/index.cjs
CHANGED
|
@@ -508,13 +508,13 @@ catch (e) {
|
|
|
508
508
|
* Logger utility that respects the debug flag in the configuration
|
|
509
509
|
*/
|
|
510
510
|
const logger = {
|
|
511
|
-
debug: (message, ...args) => {
|
|
512
|
-
if (getConfig().debug) {
|
|
511
|
+
debug: (message, force, ...args) => {
|
|
512
|
+
if (force || getConfig().debug) {
|
|
513
513
|
console.debug(message, ...args);
|
|
514
514
|
}
|
|
515
515
|
},
|
|
516
|
-
info: (message, ...args) => {
|
|
517
|
-
if (getConfig().debug) {
|
|
516
|
+
info: (message, force, ...args) => {
|
|
517
|
+
if (force || getConfig().debug) {
|
|
518
518
|
console.log(message, ...args);
|
|
519
519
|
}
|
|
520
520
|
},
|
|
@@ -640,11 +640,27 @@ class TokenManager {
|
|
|
640
640
|
*/
|
|
641
641
|
refresh(ctx, refreshToken, options, headers) {
|
|
642
642
|
return __awaiter(this, void 0, void 0, function* () {
|
|
643
|
+
logger.debug('[TokenKit] Starting token refresh', !!this.config.debug);
|
|
643
644
|
try {
|
|
644
|
-
|
|
645
|
+
const bundle = yield this.performRefresh(ctx, refreshToken, options, headers);
|
|
646
|
+
if (bundle) {
|
|
647
|
+
if (this.config.onRefresh) {
|
|
648
|
+
yield this.config.onRefresh(bundle, ctx);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
logger.debug('[TokenKit] Token refresh returned no bundle (invalid or expired)', !!this.config.debug);
|
|
653
|
+
if (this.config.onRefreshError) {
|
|
654
|
+
yield this.config.onRefreshError(new AuthError('Refresh token invalid or expired', 401), ctx);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
return bundle;
|
|
645
658
|
}
|
|
646
659
|
catch (error) {
|
|
647
|
-
|
|
660
|
+
logger.debug(`[TokenKit] Token refresh failed: ${error.message}`, !!this.config.debug);
|
|
661
|
+
if (this.config.onRefreshError) {
|
|
662
|
+
yield this.config.onRefreshError(error, ctx);
|
|
663
|
+
}
|
|
648
664
|
throw error;
|
|
649
665
|
}
|
|
650
666
|
});
|
|
@@ -723,14 +739,19 @@ class TokenManager {
|
|
|
723
739
|
const tokens = retrieveTokens(ctx, this.config.cookies);
|
|
724
740
|
// No tokens
|
|
725
741
|
if (!tokens.accessToken || !tokens.refreshToken || !tokens.expiresAt) {
|
|
742
|
+
logger.debug('[TokenKit] No valid session found, refresh impossible', !!this.config.debug);
|
|
726
743
|
return null;
|
|
727
744
|
}
|
|
728
745
|
// Token expired or force refresh
|
|
729
|
-
|
|
746
|
+
const expired = isExpired(tokens.expiresAt, now, this.config.policy);
|
|
747
|
+
if (force || expired) {
|
|
748
|
+
logger.debug(`[TokenKit] Token ${force ? 'force refresh' : 'expired'}, refreshing...`, !!this.config.debug);
|
|
730
749
|
const flightKey = this.createFlightKey(tokens.refreshToken);
|
|
731
750
|
const bundle = yield this.singleFlight.execute(flightKey, () => this.refresh(ctx, tokens.refreshToken, options, headers));
|
|
732
|
-
if (!bundle)
|
|
751
|
+
if (!bundle) {
|
|
752
|
+
logger.debug('[TokenKit] Refresh returned no bundle, session lost', !!this.config.debug);
|
|
733
753
|
return null;
|
|
754
|
+
}
|
|
734
755
|
// Ensure tokens are stored in the current context (in case of shared flight)
|
|
735
756
|
storeTokens(ctx, bundle, this.config.cookies);
|
|
736
757
|
return {
|
|
@@ -742,19 +763,26 @@ class TokenManager {
|
|
|
742
763
|
}
|
|
743
764
|
// Proactive refresh
|
|
744
765
|
if (shouldRefresh(tokens.expiresAt, now, tokens.lastRefreshAt, this.config.policy)) {
|
|
766
|
+
logger.debug('[TokenKit] Token near expiration, performing proactive refresh', !!this.config.debug);
|
|
745
767
|
const flightKey = this.createFlightKey(tokens.refreshToken);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
768
|
+
try {
|
|
769
|
+
const bundle = yield this.singleFlight.execute(flightKey, () => this.refresh(ctx, tokens.refreshToken, options, headers));
|
|
770
|
+
if (bundle) {
|
|
771
|
+
logger.debug('[TokenKit] Proactive refresh successful', !!this.config.debug);
|
|
772
|
+
// Ensure tokens are stored in the current context (in case of shared flight)
|
|
773
|
+
storeTokens(ctx, bundle, this.config.cookies);
|
|
774
|
+
return {
|
|
775
|
+
accessToken: bundle.accessToken,
|
|
776
|
+
expiresAt: bundle.accessExpiresAt,
|
|
777
|
+
tokenType: bundle.tokenType,
|
|
778
|
+
payload: (_d = (_c = bundle.sessionPayload) !== null && _c !== void 0 ? _c : parseJWTPayload(bundle.accessToken)) !== null && _d !== void 0 ? _d : undefined,
|
|
779
|
+
};
|
|
780
|
+
}
|
|
756
781
|
}
|
|
757
|
-
|
|
782
|
+
catch (error) {
|
|
783
|
+
logger.debug(`[TokenKit] Proactive refresh failed: ${error.message}. Continuing with current token.`, !!this.config.debug);
|
|
784
|
+
}
|
|
785
|
+
// Refresh failed or returned no bundle, check if tokens still exist
|
|
758
786
|
const currentTokens = retrieveTokens(ctx, this.config.cookies);
|
|
759
787
|
if (!currentTokens.accessToken) {
|
|
760
788
|
return null;
|
|
@@ -796,7 +824,7 @@ class TokenManager {
|
|
|
796
824
|
}
|
|
797
825
|
catch (error) {
|
|
798
826
|
// Ignore logout endpoint errors
|
|
799
|
-
logger.debug('[TokenKit] Logout endpoint failed:', error);
|
|
827
|
+
logger.debug('[TokenKit] Logout endpoint failed:', !!this.config.debug, error);
|
|
800
828
|
}
|
|
801
829
|
finally {
|
|
802
830
|
clearTimeout(timeoutId);
|
|
@@ -941,7 +969,7 @@ function createMiddleware() {
|
|
|
941
969
|
else if (config.context) {
|
|
942
970
|
contextStrategy = 'custom (external AsyncLocalStorage)';
|
|
943
971
|
}
|
|
944
|
-
logger.debug(`[TokenKit] Middleware initialized (auth: ${authStatus}, context: ${contextStrategy})
|
|
972
|
+
logger.debug(`[TokenKit] Middleware initialized (auth: ${authStatus}, context: ${contextStrategy})`, !!config.debug);
|
|
945
973
|
globalStorage[LOGGED_KEY] = true;
|
|
946
974
|
}
|
|
947
975
|
const runLogic = () => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -953,7 +981,7 @@ function createMiddleware() {
|
|
|
953
981
|
}
|
|
954
982
|
catch (error) {
|
|
955
983
|
// Log only the message to avoid leaking sensitive data in the error object
|
|
956
|
-
logger.debug('[TokenKit] Automatic token rotation failed:', error.message || error);
|
|
984
|
+
logger.debug('[TokenKit] Automatic token rotation failed:', !!config.debug, error.message || error);
|
|
957
985
|
}
|
|
958
986
|
}
|
|
959
987
|
return next();
|
|
@@ -998,7 +1026,7 @@ class APIClient {
|
|
|
998
1026
|
* Get token manager
|
|
999
1027
|
*/
|
|
1000
1028
|
get tokenManager() {
|
|
1001
|
-
var _a, _b;
|
|
1029
|
+
var _a, _b, _c;
|
|
1002
1030
|
const config = this.config;
|
|
1003
1031
|
if (!config.auth)
|
|
1004
1032
|
return undefined;
|
|
@@ -1014,8 +1042,8 @@ class APIClient {
|
|
|
1014
1042
|
if (!this._localTokenManager ||
|
|
1015
1043
|
this._lastUsedAuth !== config.auth ||
|
|
1016
1044
|
this._lastUsedBaseURL !== config.baseURL) {
|
|
1017
|
-
// Merge client-level fetch and
|
|
1018
|
-
const authConfig = Object.assign(Object.assign({}, config.auth), { fetch: (_a = config.auth.fetch) !== null && _a !== void 0 ? _a : config.fetch, dangerouslyIgnoreCertificateErrors: (_b = config.auth.dangerouslyIgnoreCertificateErrors) !== null && _b !== void 0 ? _b : config.dangerouslyIgnoreCertificateErrors });
|
|
1045
|
+
// Merge client-level fetch, SSL and debug settings into auth config
|
|
1046
|
+
const authConfig = Object.assign(Object.assign({}, config.auth), { fetch: (_a = config.auth.fetch) !== null && _a !== void 0 ? _a : config.fetch, dangerouslyIgnoreCertificateErrors: (_b = config.auth.dangerouslyIgnoreCertificateErrors) !== null && _b !== void 0 ? _b : config.dangerouslyIgnoreCertificateErrors, debug: (_c = config.auth.debug) !== null && _c !== void 0 ? _c : config.debug });
|
|
1019
1047
|
this._localTokenManager = new TokenManager(authConfig, config.baseURL);
|
|
1020
1048
|
this._lastUsedAuth = config.auth;
|
|
1021
1049
|
this._lastUsedBaseURL = config.baseURL;
|
|
@@ -1104,8 +1132,10 @@ class APIClient {
|
|
|
1104
1132
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1105
1133
|
var _a, _b, _c, _d, _e;
|
|
1106
1134
|
const method = config.method.toUpperCase();
|
|
1135
|
+
const debug = this.config.debug;
|
|
1107
1136
|
// Ensure valid session (if auth is enabled)
|
|
1108
1137
|
if (this.tokenManager && !config.skipAuth) {
|
|
1138
|
+
logger.debug(`[TokenKit] Ensuring valid session for ${method} ${config.url}`, !!debug);
|
|
1109
1139
|
yield this.tokenManager.ensure(ctx, config.auth, config.headers);
|
|
1110
1140
|
}
|
|
1111
1141
|
// Build full URL
|
|
@@ -1143,12 +1173,15 @@ class APIClient {
|
|
|
1143
1173
|
clearTimeout(timeoutId);
|
|
1144
1174
|
// Handle 401 (try refresh and retry once)
|
|
1145
1175
|
if (response.status === 401 && this.tokenManager && !config.skipAuth && attempt === 1) {
|
|
1176
|
+
logger.debug('[TokenKit] Received 401, attempting force refresh and retry...', !!debug);
|
|
1146
1177
|
// Clear and try fresh session (force refresh)
|
|
1147
1178
|
const session = yield this.tokenManager.ensure(ctx, config.auth, config.headers, true);
|
|
1148
1179
|
if (session) {
|
|
1180
|
+
logger.debug('[TokenKit] Force refresh successful, retrying request...', !!debug);
|
|
1149
1181
|
// Retry with new token
|
|
1150
1182
|
return this.executeRequest(config, ctx, attempt + 1);
|
|
1151
1183
|
}
|
|
1184
|
+
logger.debug('[TokenKit] Force refresh failed or returned no session', !!debug);
|
|
1152
1185
|
}
|
|
1153
1186
|
// Parse response
|
|
1154
1187
|
const apiResponse = yield this.parseResponse(response, fullURL);
|
|
@@ -1386,7 +1419,7 @@ function tokenKit(config) {
|
|
|
1386
1419
|
}
|
|
1387
1420
|
// Always inject the client-side script for idle monitoring
|
|
1388
1421
|
injectScript('page', `import 'astro-tokenkit/client-init';`);
|
|
1389
|
-
logger.debug('[TokenKit] Integration initialized');
|
|
1422
|
+
logger.debug('[TokenKit] Integration initialized', !!config.debug);
|
|
1390
1423
|
},
|
|
1391
1424
|
},
|
|
1392
1425
|
};
|