@mcp-abap-adt/auth-broker 0.2.13 → 0.2.14
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/CHANGELOG.md +21 -0
- package/README.md +41 -7
- package/dist/AuthBroker.d.ts.map +1 -1
- package/dist/AuthBroker.js +55 -6
- package/dist/__tests__/helpers/testLogger.d.ts +1 -0
- package/dist/__tests__/helpers/testLogger.d.ts.map +1 -1
- package/dist/__tests__/helpers/testLogger.js +21 -48
- package/dist/utils/formatting.d.ts +16 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +34 -0
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,27 @@ Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the co
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [0.2.14] - 2025-12-26
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- **Structured logging**: Added detailed logging throughout `AuthBroker` for better debugging and observability
|
|
18
|
+
- Logs broker initialization with configuration details
|
|
19
|
+
- Logs token retrieval operations with formatted tokens (start...end format)
|
|
20
|
+
- Logs token persistence with expiration dates in readable format
|
|
21
|
+
- Logs session state checks with token and refresh token information
|
|
22
|
+
- Uses `formatToken()` and `formatExpirationDate()` utilities for consistent formatting
|
|
23
|
+
- **Token formatting utilities**: Added `formatExpirationDate()` function to `utils/formatting.ts` for readable date/time formatting (e.g., "2025-12-25 19:21:27 UTC")
|
|
24
|
+
- **Test configuration**: Added `forceExit: true` to `jest.config.js` to prevent test hanging after completion
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- **Dependencies**: Updated `@mcp-abap-adt/auth-providers` from `^0.2.8` to `^0.2.10`
|
|
28
|
+
- **Dependencies**: Updated `@mcp-abap-adt/auth-stores` from `^0.2.9` to `^0.2.10`
|
|
29
|
+
- **Logging format**: All token logging now uses formatted tokens (shows first 25 and last 25 characters, skipping middle)
|
|
30
|
+
- **Logging format**: All expiration date logging now uses readable date/time format instead of raw timestamps
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- **Test hanging**: Fixed issue where tests would hang after completion by adding `forceExit: true` to Jest configuration
|
|
34
|
+
|
|
14
35
|
## [0.2.13] - 2025-12-26
|
|
15
36
|
|
|
16
37
|
### Changed
|
package/README.md
CHANGED
|
@@ -177,10 +177,14 @@ const connection = new JwtAbapConnection(config, tokenRefresher);
|
|
|
177
177
|
|
|
178
178
|
#### Debugging Variables
|
|
179
179
|
|
|
180
|
-
- `
|
|
180
|
+
- `DEBUG_BROKER` - Enable debug logging for `auth-broker` package (short name)
|
|
181
181
|
- Set to `true` to enable logging (default: `false`)
|
|
182
182
|
- When enabled, logs authentication steps, token operations, and error details
|
|
183
183
|
- Can be explicitly disabled by setting to `false`
|
|
184
|
+
- Example: `DEBUG_BROKER=true npm test`
|
|
185
|
+
|
|
186
|
+
- `DEBUG_AUTH_BROKER` - Long name (backward compatibility)
|
|
187
|
+
- Same as `DEBUG_BROKER`, but longer name
|
|
184
188
|
- Example: `DEBUG_AUTH_BROKER=true npm test`
|
|
185
189
|
|
|
186
190
|
- `LOG_LEVEL` - Control log verbosity level
|
|
@@ -189,18 +193,48 @@ const connection = new JwtAbapConnection(config, tokenRefresher);
|
|
|
189
193
|
- `info` - Informational messages, warnings, and errors
|
|
190
194
|
- `warn` - Warnings and errors only
|
|
191
195
|
- `error` - Errors only
|
|
192
|
-
- Example: `LOG_LEVEL=debug
|
|
196
|
+
- Example: `LOG_LEVEL=debug DEBUG_BROKER=true npm test`
|
|
193
197
|
|
|
194
198
|
- `DEBUG` - Alternative way to enable debugging
|
|
195
199
|
- Set to `true` to enable all debug logging
|
|
196
|
-
- Or set to a string containing `auth-broker` to enable only this package
|
|
197
|
-
- Example: `DEBUG=true npm test` or `DEBUG=auth-broker npm test`
|
|
200
|
+
- Or set to a string containing `broker` or `auth-broker` to enable only this package
|
|
201
|
+
- Example: `DEBUG=true npm test` or `DEBUG=broker npm test` or `DEBUG=auth-broker npm test`
|
|
198
202
|
|
|
199
203
|
**Note**: For debugging related packages:
|
|
200
|
-
- `DEBUG_AUTH_STORES` - Enable logging for `@mcp-abap-adt/auth-stores` package
|
|
201
|
-
- `DEBUG_AUTH_PROVIDERS` - Enable logging for `@mcp-abap-adt/auth-providers` package
|
|
204
|
+
- `DEBUG_STORES` (short) or `DEBUG_AUTH_STORES` (long) - Enable logging for `@mcp-abap-adt/auth-stores` package
|
|
205
|
+
- `DEBUG_PROVIDER` (short) or `DEBUG_AUTH_PROVIDERS` (long) - Enable logging for `@mcp-abap-adt/auth-providers` package
|
|
206
|
+
|
|
207
|
+
**Legacy Support**: `DEBUG_AUTH_LOG` is still supported for backward compatibility (equivalent to `DEBUG_BROKER=true LOG_LEVEL=debug`)
|
|
208
|
+
|
|
209
|
+
### Logging Features
|
|
210
|
+
|
|
211
|
+
When logging is enabled (via `DEBUG_BROKER=true` or `DEBUG_AUTH_BROKER=true`), the broker provides detailed structured logging:
|
|
212
|
+
|
|
213
|
+
**What is logged:**
|
|
214
|
+
- **Broker initialization**: Configuration details, stores, token provider, browser settings
|
|
215
|
+
- **Token retrieval**: Session state checks, token presence, refresh token availability
|
|
216
|
+
- **Token operations**: Token requests via provider, received tokens with expiration information
|
|
217
|
+
- **Token persistence**: Saving tokens to session with formatted token values and expiration dates
|
|
218
|
+
- **Error context**: Detailed error information with file paths, error codes, missing fields
|
|
219
|
+
|
|
220
|
+
**Logging Features:**
|
|
221
|
+
- **Token Formatting**: Tokens are logged in truncated format (first 25 and last 25 characters, skipping middle) for security and readability
|
|
222
|
+
- **Date Formatting**: Expiration dates are logged in readable format (e.g., "2025-12-25 19:21:27 UTC") instead of raw timestamps
|
|
223
|
+
- **Structured Logging**: Uses `DefaultLogger` from `@mcp-abap-adt/logger` for proper formatting with icons and level prefixes
|
|
224
|
+
- **Log Levels**: Controlled via `LOG_LEVEL` or `AUTH_LOG_LEVEL` environment variable (error, warn, info, debug)
|
|
225
|
+
|
|
226
|
+
Example output with `DEBUG_BROKER=true LOG_LEVEL=info`:
|
|
227
|
+
```
|
|
228
|
+
[INFO] ℹ️ [AUTH-BROKER] Broker initialized: hasServiceKeyStore(true), hasSessionStore(true), hasTokenProvider(true), browser(system), allowBrowserAuth(true)
|
|
229
|
+
[INFO] ℹ️ [AUTH-BROKER] Getting token for destination: TRIAL
|
|
230
|
+
[INFO] ℹ️ [AUTH-BROKER] Session check for TRIAL: hasToken(true), hasAuthConfig(true), hasServiceUrl(true), serviceUrl(https://...abap...), authorizationToken(eyJ0eXAiOiJKV1QiLCJqaWQiO...Q5ti7aYmEzItIDuLp7axNYo6w), hasRefreshToken(true)
|
|
231
|
+
[INFO] ℹ️ [AUTH-BROKER] Requesting tokens for TRIAL via session
|
|
232
|
+
[INFO] ℹ️ [AUTH-BROKER] Tokens received for TRIAL: authorizationToken(eyJ0eXAiOiJKV1QiLCJqaWQiO...Q5ti7aYmEzItIDuLp7axNYo6w), hasRefreshToken(true), authType(authorization_code), expiresIn(43199), expiresAt(2025-12-26 20:15:30 UTC)
|
|
233
|
+
[INFO] ℹ️ [AUTH-BROKER] Saving tokens to session for TRIAL: serviceUrl(https://...abap...), authorizationToken(eyJ0eXAiOiJKV1QiLCJqaWQiO...Q5ti7aYmEzItIDuLp7axNYo6w), hasRefreshToken(true), expiresAt(2025-12-26 20:15:30 UTC)
|
|
234
|
+
[INFO] ℹ️ [AUTH-BROKER] Token retrieved for TRIAL (via session): authorizationToken(eyJ0eXAiOiJKV1QiLCJqaWQiO...Q5ti7aYmEzItIDuLp7axNYo6w)
|
|
235
|
+
```
|
|
202
236
|
|
|
203
|
-
**
|
|
237
|
+
**Note**: Logging only works when a logger is explicitly provided to the broker constructor. The broker will not output anything to console if no logger is passed.
|
|
204
238
|
|
|
205
239
|
### File Structure
|
|
206
240
|
|
package/dist/AuthBroker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,eAAe,EAGrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EACV,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACd,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,eAAe,EAGrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EACV,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACd,MAAM,qBAAqB,CAAC;AA6C7B;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,YAAY,EAAE,aAAa,CAAC;IAC5B,uEAAuE;IACvE,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,4IAA4I;IAC5I,aAAa,EAAE,cAAc,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,gBAAgB,CAAU;IAElC;;;;;;;;;;;OAWG;gBACS,MAAM,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO;IAsFxE;;OAEG;YACW,eAAe;IA0D7B;;OAEG;YACW,aAAa;IAoD3B;;OAEG;YACW,oCAAoC;IA4ClD;;OAEG;YACW,kBAAkB;YAkClB,aAAa;YA0Db,kBAAkB;IAgDhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkJpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASxD;;;;OAIG;IACG,sBAAsB,CAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAoEvC;;;;OAIG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAgEpC;;;;;;;;;;;;;;;;OAgBG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe;CAqB3D"}
|
package/dist/AuthBroker.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.AuthBroker = void 0;
|
|
7
7
|
const interfaces_1 = require("@mcp-abap-adt/interfaces");
|
|
8
|
+
const formatting_1 = require("./utils/formatting");
|
|
8
9
|
/**
|
|
9
10
|
* No-op logger implementation for default fallback when logger is not provided
|
|
10
11
|
*/
|
|
@@ -108,7 +109,13 @@ class AuthBroker {
|
|
|
108
109
|
this.allowBrowserAuth = config.allowBrowserAuth ?? true;
|
|
109
110
|
// Log successful initialization
|
|
110
111
|
const hasServiceKeyStore = !!this.serviceKeyStore;
|
|
111
|
-
this.logger?.
|
|
112
|
+
this.logger?.info('[AuthBroker] Broker initialized', {
|
|
113
|
+
hasServiceKeyStore,
|
|
114
|
+
hasSessionStore: true,
|
|
115
|
+
hasTokenProvider: true,
|
|
116
|
+
browser: this.browser,
|
|
117
|
+
allowBrowserAuth: this.allowBrowserAuth,
|
|
118
|
+
});
|
|
112
119
|
}
|
|
113
120
|
/**
|
|
114
121
|
* Load session data (connection and authorization configs)
|
|
@@ -246,13 +253,25 @@ class AuthBroker {
|
|
|
246
253
|
}
|
|
247
254
|
}
|
|
248
255
|
async requestTokens(destination, sourceLabel) {
|
|
249
|
-
this.logger?.
|
|
256
|
+
this.logger?.info(`[AuthBroker] Requesting tokens for ${destination} via ${sourceLabel}`);
|
|
250
257
|
try {
|
|
251
258
|
const getTokens = this.tokenProvider.getTokens;
|
|
252
259
|
if (!getTokens) {
|
|
253
260
|
throw new Error('AuthBroker: tokenProvider.getTokens is required');
|
|
254
261
|
}
|
|
255
|
-
|
|
262
|
+
const tokenResult = await getTokens.call(this.tokenProvider);
|
|
263
|
+
const expiresAt = tokenResult.expiresIn
|
|
264
|
+
? Date.now() + tokenResult.expiresIn * 1000
|
|
265
|
+
: undefined;
|
|
266
|
+
this.logger?.info(`[AuthBroker] Tokens received for ${destination}`, {
|
|
267
|
+
authorizationToken: (0, formatting_1.formatToken)(tokenResult.authorizationToken),
|
|
268
|
+
hasRefreshToken: !!tokenResult.refreshToken,
|
|
269
|
+
refreshToken: (0, formatting_1.formatToken)(tokenResult.refreshToken),
|
|
270
|
+
authType: tokenResult.authType,
|
|
271
|
+
expiresIn: tokenResult.expiresIn,
|
|
272
|
+
expiresAt: expiresAt ? (0, formatting_1.formatExpirationDate)(expiresAt) : undefined,
|
|
273
|
+
});
|
|
274
|
+
return tokenResult;
|
|
256
275
|
}
|
|
257
276
|
catch (error) {
|
|
258
277
|
if (hasErrorCode(error)) {
|
|
@@ -289,6 +308,17 @@ class AuthBroker {
|
|
|
289
308
|
...authConfig,
|
|
290
309
|
refreshToken: tokenResult.refreshToken ?? authConfig.refreshToken,
|
|
291
310
|
};
|
|
311
|
+
const expiresAt = tokenResult.expiresIn
|
|
312
|
+
? Date.now() + tokenResult.expiresIn * 1000
|
|
313
|
+
: undefined;
|
|
314
|
+
this.logger?.info(`[AuthBroker] Saving tokens to session for ${destination}`, {
|
|
315
|
+
serviceUrl,
|
|
316
|
+
authorizationToken: (0, formatting_1.formatToken)(token),
|
|
317
|
+
hasRefreshToken: !!authorizationConfig.refreshToken,
|
|
318
|
+
refreshToken: (0, formatting_1.formatToken)(authorizationConfig.refreshToken),
|
|
319
|
+
expiresIn: tokenResult.expiresIn,
|
|
320
|
+
expiresAt: expiresAt ? (0, formatting_1.formatExpirationDate)(expiresAt) : undefined,
|
|
321
|
+
});
|
|
292
322
|
await this.saveTokenToSession(destination, connectionConfigWithServiceUrl, authorizationConfig);
|
|
293
323
|
}
|
|
294
324
|
/**
|
|
@@ -332,7 +362,7 @@ class AuthBroker {
|
|
|
332
362
|
* @throws Error if session initialization fails or authentication failed
|
|
333
363
|
*/
|
|
334
364
|
async getToken(destination) {
|
|
335
|
-
this.logger?.
|
|
365
|
+
this.logger?.info(`[AuthBroker] Getting token for destination: ${destination}`);
|
|
336
366
|
// Load session data
|
|
337
367
|
const { connConfig, authConfig } = await this.loadSessionData(destination);
|
|
338
368
|
// Get serviceUrl (required)
|
|
@@ -340,7 +370,15 @@ class AuthBroker {
|
|
|
340
370
|
// Check if we have token or UAA credentials
|
|
341
371
|
const hasToken = !!connConfig?.authorizationToken;
|
|
342
372
|
const hasAuthConfig = !!authConfig;
|
|
343
|
-
this.logger?.
|
|
373
|
+
this.logger?.info(`[AuthBroker] Session check for ${destination}`, {
|
|
374
|
+
hasToken,
|
|
375
|
+
hasAuthConfig,
|
|
376
|
+
hasServiceUrl: !!serviceUrl,
|
|
377
|
+
serviceUrl,
|
|
378
|
+
authorizationToken: (0, formatting_1.formatToken)(connConfig?.authorizationToken),
|
|
379
|
+
hasRefreshToken: !!authConfig?.refreshToken,
|
|
380
|
+
refreshToken: (0, formatting_1.formatToken)(authConfig?.refreshToken),
|
|
381
|
+
});
|
|
344
382
|
// Step 0: Initialize Session with Token (if needed)
|
|
345
383
|
if (!hasToken && !hasAuthConfig) {
|
|
346
384
|
if (!this.allowBrowserAuth) {
|
|
@@ -353,6 +391,9 @@ class AuthBroker {
|
|
|
353
391
|
const serviceKeyAuthConfig = await this.getAuthorizationConfigFromServiceKey(destination);
|
|
354
392
|
const tokenResult = await this.requestTokens(destination, 'serviceKey');
|
|
355
393
|
await this.persistTokenResult(destination, serviceUrl, connConfig, serviceKeyAuthConfig, tokenResult);
|
|
394
|
+
this.logger?.info(`[AuthBroker] Token retrieved for ${destination} (initialized from service key)`, {
|
|
395
|
+
authorizationToken: (0, formatting_1.formatToken)(tokenResult.authorizationToken),
|
|
396
|
+
});
|
|
356
397
|
return tokenResult.authorizationToken;
|
|
357
398
|
}
|
|
358
399
|
// Step 1: Request tokens via provider (provider handles token lifecycle internally)
|
|
@@ -371,6 +412,9 @@ class AuthBroker {
|
|
|
371
412
|
try {
|
|
372
413
|
const tokenResult = await this.requestTokens(destination, 'session');
|
|
373
414
|
await this.persistTokenResult(destination, serviceUrl, connConfig, authConfig, tokenResult);
|
|
415
|
+
this.logger?.info(`[AuthBroker] Token retrieved for ${destination} (via session)`, {
|
|
416
|
+
authorizationToken: (0, formatting_1.formatToken)(tokenResult.authorizationToken),
|
|
417
|
+
});
|
|
374
418
|
return tokenResult.authorizationToken;
|
|
375
419
|
}
|
|
376
420
|
catch (error) {
|
|
@@ -394,6 +438,9 @@ class AuthBroker {
|
|
|
394
438
|
const serviceKeyAuthConfig = await this.getAuthorizationConfigFromServiceKey(destination);
|
|
395
439
|
const tokenResult = await this.requestTokens(destination, 'serviceKey');
|
|
396
440
|
await this.persistTokenResult(destination, serviceUrl, connConfig, serviceKeyAuthConfig, tokenResult);
|
|
441
|
+
this.logger?.info(`[AuthBroker] Token retrieved for ${destination} (fallback to service key)`, {
|
|
442
|
+
authorizationToken: (0, formatting_1.formatToken)(tokenResult.authorizationToken),
|
|
443
|
+
});
|
|
397
444
|
return tokenResult.authorizationToken;
|
|
398
445
|
}
|
|
399
446
|
/**
|
|
@@ -481,7 +528,9 @@ class AuthBroker {
|
|
|
481
528
|
this.logger?.warn(`Failed to get connection config from session store for ${destination}: ${getErrorMessage(error)}`);
|
|
482
529
|
}
|
|
483
530
|
if (sessionConnConfig) {
|
|
484
|
-
|
|
531
|
+
const tokenLength = sessionConnConfig.authorizationToken?.length || 0;
|
|
532
|
+
const formattedToken = (0, formatting_1.formatToken)(sessionConnConfig.authorizationToken);
|
|
533
|
+
this.logger?.debug(`Connection config from session for ${destination}: token(${tokenLength} chars${formattedToken ? `, ${formattedToken}` : ''}), serviceUrl(${sessionConnConfig.serviceUrl ? 'yes' : 'no'})`);
|
|
485
534
|
return sessionConnConfig;
|
|
486
535
|
}
|
|
487
536
|
// Fall back to service key store (has URLs but no tokens) if available
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testLogger.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/testLogger.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"testLogger.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/testLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAGxD,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,MAAe,GAAG,OAAO,CAmDjE"}
|
|
@@ -1,80 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Test logger with environment variable control
|
|
4
|
+
* Uses DefaultLogger from @mcp-abap-adt/logger for proper formatting
|
|
4
5
|
*/
|
|
5
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
7
|
exports.createTestLogger = createTestLogger;
|
|
7
|
-
|
|
8
|
-
const level = process.env.LOG_LEVEL?.toLowerCase() || 'info';
|
|
9
|
-
const levels = ['debug', 'info', 'warn', 'error'];
|
|
10
|
-
return levels.includes(level) ? level : 'info';
|
|
11
|
-
}
|
|
12
|
-
function shouldLog(level) {
|
|
13
|
-
const currentLevel = getLogLevel();
|
|
14
|
-
const levels = ['debug', 'info', 'warn', 'error'];
|
|
15
|
-
return levels.indexOf(level) >= levels.indexOf(currentLevel);
|
|
16
|
-
}
|
|
8
|
+
const logger_1 = require("@mcp-abap-adt/logger");
|
|
17
9
|
function createTestLogger(prefix = 'TEST') {
|
|
18
10
|
// Check if logging is enabled - requires explicit enable
|
|
19
11
|
const isEnabled = () => {
|
|
20
|
-
// Explicitly disabled
|
|
21
|
-
if (process.env.
|
|
12
|
+
// Explicitly disabled (support both short and long names)
|
|
13
|
+
if (process.env.DEBUG_BROKER === 'false' ||
|
|
14
|
+
process.env.DEBUG_AUTH_BROKER === 'false') {
|
|
22
15
|
return false;
|
|
23
16
|
}
|
|
24
|
-
// Explicitly enabled
|
|
25
|
-
if (process.env.
|
|
17
|
+
// Explicitly enabled (support both short and long names)
|
|
18
|
+
if (process.env.DEBUG_BROKER === 'true' ||
|
|
19
|
+
process.env.DEBUG_AUTH_BROKER === 'true' ||
|
|
26
20
|
process.env.DEBUG === 'true' ||
|
|
21
|
+
process.env.DEBUG?.includes('broker') === true ||
|
|
27
22
|
process.env.DEBUG?.includes('auth-broker') === true) {
|
|
28
23
|
return true;
|
|
29
24
|
}
|
|
30
25
|
// Do not enable by default - require explicit enable
|
|
31
26
|
return false;
|
|
32
27
|
};
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
// If meta is an object, format it concisely
|
|
39
|
-
if (typeof meta === 'object' && !Array.isArray(meta)) {
|
|
40
|
-
const parts = [];
|
|
41
|
-
for (const [key, value] of Object.entries(meta)) {
|
|
42
|
-
if (value !== undefined && value !== null) {
|
|
43
|
-
if (typeof value === 'string' && value.length > 50) {
|
|
44
|
-
parts.push(`${key}(${value.substring(0, 50)}...)`);
|
|
45
|
-
}
|
|
46
|
-
else if (typeof value === 'boolean') {
|
|
47
|
-
parts.push(`${key}(${value})`);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
parts.push(`${key}(${value})`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return parts.length > 0 ? `${message} ${parts.join(', ')}` : message;
|
|
55
|
-
}
|
|
56
|
-
// If meta is a string or other type, append it
|
|
57
|
-
return `${message} ${String(meta)}`;
|
|
58
|
-
};
|
|
28
|
+
// Create DefaultLogger with appropriate log level
|
|
29
|
+
// getLogLevel respects AUTH_LOG_LEVEL env var and defaults to INFO
|
|
30
|
+
const baseLogger = new logger_1.DefaultLogger((0, logger_1.getLogLevel)());
|
|
31
|
+
// Return wrapper that checks if logging is enabled
|
|
59
32
|
return {
|
|
60
33
|
debug: (message, meta) => {
|
|
61
|
-
if (isEnabled()
|
|
62
|
-
|
|
34
|
+
if (isEnabled()) {
|
|
35
|
+
baseLogger.debug(`[${prefix}] ${message}`, meta);
|
|
63
36
|
}
|
|
64
37
|
},
|
|
65
38
|
info: (message, meta) => {
|
|
66
|
-
if (isEnabled()
|
|
67
|
-
|
|
39
|
+
if (isEnabled()) {
|
|
40
|
+
baseLogger.info(`[${prefix}] ${message}`, meta);
|
|
68
41
|
}
|
|
69
42
|
},
|
|
70
43
|
warn: (message, meta) => {
|
|
71
|
-
if (isEnabled()
|
|
72
|
-
|
|
44
|
+
if (isEnabled()) {
|
|
45
|
+
baseLogger.warn(`[${prefix}] ${message}`, meta);
|
|
73
46
|
}
|
|
74
47
|
},
|
|
75
48
|
error: (message, meta) => {
|
|
76
|
-
if (isEnabled()
|
|
77
|
-
|
|
49
|
+
if (isEnabled()) {
|
|
50
|
+
baseLogger.error(`[${prefix}] ${message}`, meta);
|
|
78
51
|
}
|
|
79
52
|
},
|
|
80
53
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formatting utilities for logging
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format token for logging (start...end)
|
|
6
|
+
* @param token Token string to format
|
|
7
|
+
* @returns Formatted token string or undefined if token is empty
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatToken(token?: string): string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Format timestamp to readable date/time string
|
|
12
|
+
* @param timestamp Timestamp in milliseconds
|
|
13
|
+
* @returns Formatted date string (e.g., "2025-12-25 19:21:27 UTC")
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatExpirationDate(timestamp: number): string;
|
|
16
|
+
//# sourceMappingURL=formatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAS9D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Formatting utilities for logging
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.formatToken = formatToken;
|
|
7
|
+
exports.formatExpirationDate = formatExpirationDate;
|
|
8
|
+
/**
|
|
9
|
+
* Format token for logging (start...end)
|
|
10
|
+
* @param token Token string to format
|
|
11
|
+
* @returns Formatted token string or undefined if token is empty
|
|
12
|
+
*/
|
|
13
|
+
function formatToken(token) {
|
|
14
|
+
if (!token)
|
|
15
|
+
return undefined;
|
|
16
|
+
if (token.length <= 50)
|
|
17
|
+
return token;
|
|
18
|
+
return `${token.substring(0, 25)}...${token.substring(token.length - 25)}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Format timestamp to readable date/time string
|
|
22
|
+
* @param timestamp Timestamp in milliseconds
|
|
23
|
+
* @returns Formatted date string (e.g., "2025-12-25 19:21:27 UTC")
|
|
24
|
+
*/
|
|
25
|
+
function formatExpirationDate(timestamp) {
|
|
26
|
+
const date = new Date(timestamp);
|
|
27
|
+
const year = date.getUTCFullYear();
|
|
28
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
29
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
30
|
+
const hours = String(date.getUTCHours()).padStart(2, '0');
|
|
31
|
+
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
|
|
32
|
+
const seconds = String(date.getUTCSeconds()).padStart(2, '0');
|
|
33
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds} UTC`;
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/auth-broker",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14",
|
|
4
4
|
"description": "JWT authentication broker for MCP ABAP ADT - manages tokens based on destination headers",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -56,14 +56,15 @@
|
|
|
56
56
|
"node": ">=18.0.0"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@mcp-abap-adt/auth-providers": "^0.2.
|
|
60
|
-
"@mcp-abap-adt/auth-stores": "^0.2.
|
|
59
|
+
"@mcp-abap-adt/auth-providers": "^0.2.10",
|
|
60
|
+
"@mcp-abap-adt/auth-stores": "^0.2.10",
|
|
61
61
|
"@mcp-abap-adt/interfaces": "^0.2.14",
|
|
62
62
|
"axios": "^1.13.2",
|
|
63
63
|
"tsx": "^4.21.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@biomejs/biome": "^2.3.10",
|
|
67
|
+
"@mcp-abap-adt/logger": "^0.1.4",
|
|
67
68
|
"@types/express": "^5.0.5",
|
|
68
69
|
"@types/jest": "^30.0.0",
|
|
69
70
|
"@types/js-yaml": "^4.0.9",
|
|
@@ -71,6 +72,8 @@
|
|
|
71
72
|
"jest": "^30.2.0",
|
|
72
73
|
"jest-util": "^30.2.0",
|
|
73
74
|
"js-yaml": "^4.1.1",
|
|
75
|
+
"pino": "^10.1.0",
|
|
76
|
+
"pino-pretty": "^13.1.3",
|
|
74
77
|
"ts-jest": "^29.2.5",
|
|
75
78
|
"typescript": "^5.9.2"
|
|
76
79
|
}
|