@mcp-abap-adt/auth-broker 0.1.11 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -11,6 +11,164 @@ Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the co
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.2.1] - 2025-12-12
15
+
16
+ ### Fixed
17
+ - **ServiceUrl fallback from serviceKeyStore**: Fixed `getToken()` method to retrieve `serviceUrl` from `serviceKeyStore` when it's missing in session
18
+ - Previously, `getToken()` would throw an error immediately if `serviceUrl` was not found in session, even when it was available in `serviceKeyStore`
19
+ - Now, the method first checks session for `serviceUrl`, and if not found, attempts to retrieve it from `serviceKeyStore` before throwing an error
20
+ - This allows integration tests and real-world scenarios to work correctly when session is empty but service key contains `serviceUrl`
21
+ - Error messages now indicate that `serviceUrl` can come from either session or `serviceKeyStore`
22
+
23
+ ## [0.2.0] - 2025-12-08
24
+
25
+ ### Breaking Changes
26
+
27
+ **⚠️ IMPORTANT: This is a breaking change with NO backward compatibility. Migration is required. See Migration Guide below.**
28
+
29
+ #### Constructor Signature Changed
30
+ - **Constructor now accepts configuration object**: The constructor signature has changed from requiring all three dependencies to making `serviceKeyStore` and `tokenProvider` optional
31
+ - **No backward compatibility**: Old constructor signature is NOT supported. You must update your code to use the new signature. Migration guide provided below.
32
+ - **Before (v0.1.x)**:
33
+ ```typescript
34
+ new AuthBroker({
35
+ serviceKeyStore: serviceKeyStore, // required
36
+ sessionStore: sessionStore, // required
37
+ tokenProvider: tokenProvider, // required
38
+ }, browser?, logger?)
39
+ ```
40
+ - **After (v0.2.0)**:
41
+ ```typescript
42
+ new AuthBroker({
43
+ sessionStore: sessionStore, // required
44
+ serviceKeyStore?: serviceKeyStore, // optional
45
+ tokenProvider?: tokenProvider, // optional
46
+ }, browser?, logger?)
47
+ ```
48
+
49
+ #### New Authentication Flow
50
+ - **Three-step authentication flow**: `getToken()` now implements a new three-step flow (Step 0, Step 1, Step 2) instead of the previous six-step fallback chain
51
+ - **Direct UAA HTTP requests**: When UAA credentials are available in session, broker uses direct HTTP requests to UAA without requiring `tokenProvider`
52
+ - **Session initialization requirements**: SessionStore must contain initial session with `serviceUrl` before calling `getToken()`
53
+
54
+ ### Added
55
+
56
+ #### Direct UAA HTTP Requests
57
+ - **Direct UAA refresh_token grant**: When UAA credentials are available in session, broker can refresh tokens directly via HTTP without `tokenProvider`
58
+ - **Direct UAA client_credentials grant**: When UAA credentials are available, broker can obtain tokens directly via HTTP without `tokenProvider`
59
+ - **Automatic fallback to provider**: If direct UAA requests fail and `tokenProvider` is available, broker automatically falls back to provider
60
+
61
+ #### Flexible Configuration
62
+ - **Optional serviceKeyStore**: `serviceKeyStore` is now optional - only needed for initializing sessions from service keys
63
+ - **Optional tokenProvider**: `tokenProvider` is now optional - only needed for browser authentication or when direct UAA requests fail
64
+ - **Session-only mode**: Can work with only `sessionStore` if session contains valid UAA credentials (no `serviceKeyStore` or `tokenProvider` needed)
65
+
66
+ #### Enhanced Error Messages
67
+ - **Step-based error messages**: Error messages now indicate which step failed (Step 0, Step 1, or Step 2)
68
+ - **Context-aware errors**: Error messages include information about what was tried and what's available
69
+ - **Actionable errors**: Error messages suggest what to do next (e.g., "Provide serviceKeyStore to initialize from service key")
70
+
71
+ ### Changed
72
+
73
+ #### Authentication Flow (getToken)
74
+ - **Step 0: Session Initialization**:
75
+ - Checks if session has `authorizationToken` and UAA credentials
76
+ - If both empty and `serviceKeyStore` available: tries direct UAA request from service key, falls back to provider if failed
77
+ - If session has token OR UAA credentials → proceeds to Step 1
78
+ - **Step 1: Refresh Token Flow**:
79
+ - If refresh token exists: tries direct UAA refresh, falls back to provider if failed
80
+ - If successful → returns new token
81
+ - Otherwise → proceeds to Step 2
82
+ - **Step 2: UAA Credentials Flow**:
83
+ - Tries direct UAA client_credentials request, falls back to provider if failed
84
+ - If successful → returns new token
85
+ - If all failed → throws error
86
+
87
+ #### Token Refresh (refreshToken)
88
+ - **Direct UAA support**: Uses direct UAA HTTP requests when UAA credentials are available
89
+ - **Provider fallback**: Falls back to provider if direct UAA fails and provider is available
90
+
91
+ #### Dependencies
92
+ - **Added axios**: Added `axios@^1.13.2` as dependency for direct UAA HTTP requests
93
+ - **Updated interfaces**: Works with `@mcp-abap-adt/interfaces@^0.1.4+`
94
+
95
+ ### Migration Guide
96
+
97
+ #### Updating Constructor Calls
98
+
99
+ **Before (v0.1.x)**:
100
+ ```typescript
101
+ const broker = new AuthBroker({
102
+ serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']),
103
+ sessionStore: new AbapSessionStore(['/path/to/destinations']),
104
+ tokenProvider: new BtpTokenProvider(),
105
+ }, 'chrome', logger);
106
+ ```
107
+
108
+ **After (v0.2.0) - All dependencies**:
109
+ ```typescript
110
+ const broker = new AuthBroker({
111
+ sessionStore: new AbapSessionStore(['/path/to/destinations']),
112
+ serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']), // optional
113
+ tokenProvider: new BtpTokenProvider(), // optional
114
+ }, 'chrome', logger);
115
+ ```
116
+
117
+ **After (v0.2.0) - Session only (if session has UAA credentials)**:
118
+ ```typescript
119
+ const broker = new AuthBroker({
120
+ sessionStore: new AbapSessionStore(['/path/to/destinations']),
121
+ // serviceKeyStore and tokenProvider not needed if session has UAA credentials
122
+ });
123
+ ```
124
+
125
+ **After (v0.2.0) - Session + Service Key (for initialization)**:
126
+ ```typescript
127
+ const broker = new AuthBroker({
128
+ sessionStore: new AbapSessionStore(['/path/to/destinations']),
129
+ serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']),
130
+ // tokenProvider optional - direct UAA requests will be used
131
+ });
132
+ ```
133
+
134
+ #### Session Requirements
135
+
136
+ **Important**: SessionStore must contain initial session with `serviceUrl` before calling `getToken()`. If session is empty, provide `serviceKeyStore` to initialize from service key.
137
+
138
+ #### When to Provide tokenProvider
139
+
140
+ - **Required**: When initializing session from service key via browser authentication (Step 0)
141
+ - **Optional but recommended**: As fallback when direct UAA requests fail
142
+ - **Not needed**: When session contains valid UAA credentials (direct UAA requests will be used)
143
+
144
+ ### Dependencies
145
+ - Updated to work with `@mcp-abap-adt/connection` v0.2.0+ (which removed token refresh and session storage)
146
+ - Updated to work with `@mcp-abap-adt/interfaces` v0.1.4+ (which removed session state methods from `IAbapConnection`)
147
+ - Added `axios@^1.13.2` for direct UAA HTTP requests
148
+
149
+ ## [0.1.12] - 2025-12-09
150
+
151
+ ### Added
152
+ - **Debugging Environment Variables**: Added comprehensive debugging support via environment variables
153
+ - `DEBUG_AUTH_BROKER` - Enable/disable logging for auth-broker package (default: `false`)
154
+ - `LOG_LEVEL` - Control log verbosity: `debug`, `info`, `warn`, `error` (default: `info`)
155
+ - `DEBUG` - Alternative way to enable debugging (set to `true` or string containing `auth-broker`)
156
+ - Logging is disabled by default to avoid misleading output in tests
157
+ - Tests that expect errors use no-op logger to prevent error message output
158
+
159
+ ### Changed
160
+ - **Test Logger Behavior**: Modified `createTestLogger` to require explicit enable via environment variables
161
+ - No longer enabled by default in test environment (`NODE_ENV === 'test'`)
162
+ - Requires `DEBUG_AUTH_BROKER=true` or `DEBUG=true` to enable logging
163
+ - Prevents misleading error output in tests that expect errors
164
+ - Tests that expect errors now use `noOpLogger` to avoid false error messages
165
+
166
+ ### Fixed
167
+ - **Service URL Handling**: Fixed `serviceUrl` propagation for ABAP sessions
168
+ - `AuthBroker` now retrieves `serviceUrl` from `serviceKeyStore` if not provided by `tokenProvider`
169
+ - Ensures ABAP session stores receive required `serviceUrl` even when token provider doesn't return it
170
+ - Applied to all authentication flows (refresh token, UAA, browser auth)
171
+
14
172
  ## [0.1.11] - 2025-12-07
15
173
 
16
174
  ### Changed
package/README.md CHANGED
@@ -19,43 +19,84 @@ npm install @mcp-abap-adt/auth-broker
19
19
 
20
20
  ## Usage
21
21
 
22
+ ### Basic Usage (Session Only)
23
+
24
+ If your sessionStore contains valid UAA credentials, you only need to provide `sessionStore`:
25
+
26
+ ```typescript
27
+ import { AuthBroker, AbapSessionStore } from '@mcp-abap-adt/auth-broker';
28
+
29
+ // Session-only mode - works if session has UAA credentials
30
+ const broker = new AuthBroker({
31
+ sessionStore: new AbapSessionStore('/path/to/destinations'),
32
+ });
33
+
34
+ // Get token - uses direct UAA HTTP requests automatically
35
+ const token = await broker.getToken('TRIAL');
36
+ ```
37
+
38
+ ### Full Configuration (All Dependencies)
39
+
40
+ For maximum flexibility, provide all three dependencies:
41
+
22
42
  ```typescript
23
43
  import {
24
44
  AuthBroker,
25
45
  AbapServiceKeyStore,
26
46
  AbapSessionStore,
27
- SafeAbapSessionStore,
28
47
  BtpTokenProvider
29
48
  } from '@mcp-abap-adt/auth-broker';
30
49
 
31
- // Use default file-based stores (current working directory)
32
- const broker = new AuthBroker();
50
+ const broker = new AuthBroker({
51
+ sessionStore: new AbapSessionStore('/path/to/destinations'),
52
+ serviceKeyStore: new AbapServiceKeyStore('/path/to/destinations'), // optional
53
+ tokenProvider: new BtpTokenProvider(), // optional
54
+ }, 'chrome', logger);
55
+ ```
56
+
57
+ ### Session + Service Key (For Initialization)
33
58
 
34
- // Use custom file-based stores with specific paths
59
+ If you need to initialize sessions from service keys:
60
+
61
+ ```typescript
35
62
  const broker = new AuthBroker({
36
- serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']),
37
- sessionStore: new AbapSessionStore(['/path/to/destinations']),
38
- tokenProvider: new BtpTokenProvider(),
39
- }, 'chrome');
63
+ sessionStore: new AbapSessionStore('/path/to/destinations'),
64
+ serviceKeyStore: new AbapServiceKeyStore('/path/to/destinations'),
65
+ // tokenProvider optional - direct UAA requests will be used from service key
66
+ });
67
+ ```
68
+
69
+ ### In-Memory Session Store
70
+
71
+ For testing or temporary sessions:
72
+
73
+ ```typescript
74
+ import { AuthBroker, SafeAbapSessionStore } from '@mcp-abap-adt/auth-broker';
40
75
 
41
- // Use safe in-memory session store (data lost after restart)
42
76
  const broker = new AuthBroker({
43
- serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']),
44
- sessionStore: new SafeAbapSessionStore(), // In-memory, secure
45
- tokenProvider: new BtpTokenProvider(),
77
+ sessionStore: new SafeAbapSessionStore(), // In-memory, data lost after restart
46
78
  });
79
+ ```
80
+
81
+ ### Custom Browser Auth Port
47
82
 
48
- // Use BtpTokenProvider with custom browser auth port (to avoid port conflicts)
49
- const brokerWithCustomPort = new AuthBroker({
50
- serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']),
51
- sessionStore: new AbapSessionStore(['/path/to/destinations']),
83
+ To avoid port conflicts with browser authentication:
84
+
85
+ ```typescript
86
+ const broker = new AuthBroker({
87
+ sessionStore: new AbapSessionStore('/path/to/destinations'),
88
+ serviceKeyStore: new AbapServiceKeyStore('/path/to/destinations'),
52
89
  tokenProvider: new BtpTokenProvider(4001), // Custom port for OAuth callback server
53
- });
90
+ }, 'chrome');
91
+ ```
92
+
93
+ ### Getting Tokens
54
94
 
55
- // Get token for destination (loads from .env, validates, refreshes if needed)
95
+ ```typescript
96
+ // Get token - automatically uses direct UAA requests if UAA credentials available
56
97
  const token = await broker.getToken('TRIAL');
57
98
 
58
- // Force refresh token using service key
99
+ // Force refresh token
59
100
  const newToken = await broker.refreshToken('TRIAL');
60
101
  ```
61
102
 
@@ -63,8 +104,36 @@ const newToken = await broker.refreshToken('TRIAL');
63
104
 
64
105
  ### Environment Variables
65
106
 
107
+ #### Configuration Variables
108
+
66
109
  - `AUTH_BROKER_PATH` - Colon/semicolon-separated paths for searching `.env` and `.json` files (default: current working directory)
67
- - `DEBUG_AUTH_LOG` - Set to `true` to enable debug logging (default: `false`)
110
+
111
+ #### Debugging Variables
112
+
113
+ - `DEBUG_AUTH_BROKER` - Enable debug logging for `auth-broker` package
114
+ - Set to `true` to enable logging (default: `false`)
115
+ - When enabled, logs authentication steps, token operations, and error details
116
+ - Can be explicitly disabled by setting to `false`
117
+ - Example: `DEBUG_AUTH_BROKER=true npm test`
118
+
119
+ - `LOG_LEVEL` - Control log verbosity level
120
+ - Values: `debug`, `info`, `warn`, `error` (default: `info`)
121
+ - `debug` - All messages including detailed debug information
122
+ - `info` - Informational messages, warnings, and errors
123
+ - `warn` - Warnings and errors only
124
+ - `error` - Errors only
125
+ - Example: `LOG_LEVEL=debug DEBUG_AUTH_BROKER=true npm test`
126
+
127
+ - `DEBUG` - Alternative way to enable debugging
128
+ - Set to `true` to enable all debug logging
129
+ - Or set to a string containing `auth-broker` to enable only this package
130
+ - Example: `DEBUG=true npm test` or `DEBUG=auth-broker npm test`
131
+
132
+ **Note**: For debugging related packages:
133
+ - `DEBUG_AUTH_STORES` - Enable logging for `@mcp-abap-adt/auth-stores` package
134
+ - `DEBUG_AUTH_PROVIDERS` - Enable logging for `@mcp-abap-adt/auth-providers` package
135
+
136
+ **Legacy Support**: `DEBUG_AUTH_LOG` is still supported for backward compatibility (equivalent to `DEBUG_AUTH_BROKER=true LOG_LEVEL=debug`)
68
137
 
69
138
  ### File Structure
70
139
 
@@ -274,45 +343,83 @@ Instead, the consumer or `AbapSessionStore` itself should handle this:
274
343
 
275
344
  ```typescript
276
345
  new AuthBroker(
277
- stores?: {
278
- serviceKeyStore?: IServiceKeyStore;
279
- sessionStore?: ISessionStore;
280
- tokenProvider?: ITokenProvider;
346
+ config: {
347
+ sessionStore: ISessionStore; // required
348
+ serviceKeyStore?: IServiceKeyStore; // optional
349
+ tokenProvider?: ITokenProvider; // optional
281
350
  },
282
351
  browser?: string,
283
352
  logger?: ILogger
284
353
  )
285
354
  ```
286
355
 
287
- - `stores` - Optional object with custom storage implementations:
288
- - `serviceKeyStore` - Store for service keys (default: `AbapServiceKeyStore()`)
289
- - `sessionStore` - Store for session data (default: `AbapSessionStore()`)
290
- - `tokenProvider` - Token provider for token acquisition (default: `BtpTokenProvider()`)
291
- - Available implementations:
292
- - **ABAP**: `AbapServiceKeyStore(searchPaths?)`, `AbapSessionStore(searchPaths?)`, `SafeAbapSessionStore()`, `BtpTokenProvider()`
293
- - **XSUAA** (reduced scope): `XsuaaServiceKeyStore(searchPaths?)`, `XsuaaSessionStore(searchPaths?)`, `SafeXsuaaSessionStore()`, `XsuaaTokenProvider()`
294
- - **BTP** (full scope for ABAP): `AbapServiceKeyStore(searchPaths?)`, `BtpSessionStore(searchPaths?)`, `SafeBtpSessionStore()`, `BtpTokenProvider()`
356
+ **Parameters:**
357
+ - `config` - Configuration object:
358
+ - `sessionStore` - **Required** - Store for session data. Must contain initial session with `serviceUrl`
359
+ - `serviceKeyStore` - **Optional** - Store for service keys. Only needed for initializing sessions from service keys
360
+ - `tokenProvider` - **Optional** - Token provider for token acquisition. Only needed for browser authentication or when direct UAA requests fail
295
361
  - `browser` - Optional browser name for authentication (`chrome`, `edge`, `firefox`, `system`, `none`). Default: `system`
296
362
  - For XSUAA, browser is not used (client_credentials grant type) - use `'none'`
297
- - `logger` - Optional logger instance. If not provided, uses default logger
363
+ - `logger` - Optional logger instance. If not provided, uses no-op logger
298
364
 
299
- #### Methods
365
+ **When to Provide Each Dependency:**
300
366
 
301
- ##### `getToken(destination: string): Promise<string>`
367
+ - **`sessionStore` (required)**: Always required. Must contain initial session with `serviceUrl`
368
+ - **`serviceKeyStore` (optional)**:
369
+ - Required if you need to initialize sessions from service keys (Step 0)
370
+ - Not needed if session already contains UAA credentials
371
+ - **`tokenProvider` (optional)**:
372
+ - Required for browser authentication when initializing from service key (Step 0)
373
+ - Optional but recommended as fallback when direct UAA requests fail
374
+ - Not needed if session contains valid UAA credentials (direct UAA HTTP requests will be used)
375
+
376
+ **Available Implementations:**
377
+ - **ABAP**: `AbapServiceKeyStore(directory, defaultServiceUrl?, logger?)`, `AbapSessionStore(directory, defaultServiceUrl?, logger?)`, `SafeAbapSessionStore(defaultServiceUrl?, logger?)`, `BtpTokenProvider(browserAuthPort?)`
378
+ - **XSUAA** (reduced scope): `XsuaaServiceKeyStore(directory, logger?)`, `XsuaaSessionStore(directory, defaultServiceUrl, logger?)`, `SafeXsuaaSessionStore(defaultServiceUrl, logger?)`, `XsuaaTokenProvider()`
379
+ - **BTP** (full scope for ABAP): `AbapServiceKeyStore(directory, defaultServiceUrl?, logger?)`, `BtpSessionStore(directory, defaultServiceUrl, logger?)`, `SafeBtpSessionStore(defaultServiceUrl, logger?)`, `BtpTokenProvider(browserAuthPort?)`
302
380
 
303
- Gets authentication token for destination. Tries to load from session store, validates it, and refreshes if needed using a fallback chain:
381
+ #### Methods
304
382
 
305
- 1. **Check session**: Load token from session store and validate it
306
- 2. **Try refresh token**: If refresh token is available, attempt to refresh using it (via tokenProvider)
307
- 3. **Try UAA (client_credentials)**: Attempt to get token using UAA credentials (via tokenProvider)
308
- 4. **Try browser authentication**: Attempt browser-based OAuth2 flow using service key (via tokenProvider)
309
- 5. **Throw error**: If all authentication methods failed
383
+ ##### `getToken(destination: string): Promise<string>`
310
384
 
311
- **Note**: Token validation is performed only when checking existing session. Tokens obtained through refresh/UAA/browser authentication are not validated before being saved.
385
+ Gets authentication token for destination. Implements a three-step flow:
386
+
387
+ **Step 0: Initialize Session with Token (if needed)**
388
+ - Checks if session has `authorizationToken` and UAA credentials
389
+ - If both are empty and `serviceKeyStore` is available:
390
+ - Tries direct UAA request from service key (if UAA credentials available)
391
+ - If failed and `tokenProvider` available → uses provider for authentication
392
+ - If session has token OR UAA credentials → proceeds to Step 1
393
+
394
+ **Step 1: Refresh Token Flow**
395
+ - Checks if refresh token exists in session
396
+ - If refresh token exists:
397
+ - Tries direct UAA refresh (if UAA credentials in session)
398
+ - If failed and `tokenProvider` available → uses provider
399
+ - If successful → returns new token
400
+ - Otherwise → proceeds to Step 2
401
+
402
+ **Step 2: UAA Credentials Flow**
403
+ - Checks if UAA credentials exist in session or service key
404
+ - Tries direct UAA client_credentials request (if UAA credentials available)
405
+ - If failed and `tokenProvider` available → uses provider
406
+ - If successful → returns new token
407
+ - If all failed → throws error
408
+
409
+ **Important Notes:**
410
+ - If `sessionStore` contains valid UAA credentials, neither `serviceKeyStore` nor `tokenProvider` are required. Direct UAA HTTP requests will be used automatically.
411
+ - `tokenProvider` is only needed for browser authentication or when direct UAA requests fail.
412
+ - Token validation is performed only when checking existing session. Tokens obtained through refresh/UAA/browser authentication are not validated before being saved.
312
413
 
313
414
  ##### `refreshToken(destination: string): Promise<string>`
314
415
 
315
- Force refresh token for destination using service key from `{destination}.json` file.
416
+ Force refresh token for destination. Uses refresh token from session if available, otherwise uses UAA credentials from session or service key.
417
+
418
+ **Flow:**
419
+ - If refresh token exists and UAA credentials available → tries direct UAA refresh
420
+ - If direct UAA fails and `tokenProvider` available → uses provider
421
+ - If no refresh token but UAA credentials available → tries direct UAA client_credentials
422
+ - If all failed → throws error
316
423
 
317
424
  ##### `clearCache(destination: string): void`
318
425
 
@@ -346,24 +453,54 @@ import {
346
453
  XsuaaServiceKeyStore,
347
454
  XsuaaSessionStore,
348
455
  XsuaaTokenProvider,
349
- BtpTokenProvider
456
+ BtpTokenProvider,
457
+ AbapServiceKeyStore,
458
+ BtpSessionStore
350
459
  } from '@mcp-abap-adt/auth-broker';
351
460
 
352
- // XSUAA authentication (no browser needed)
461
+ // XSUAA authentication - session only (direct UAA requests)
353
462
  const xsuaaBroker = new AuthBroker({
354
- serviceKeyStore: new XsuaaServiceKeyStore(['/path/to/keys']),
355
- sessionStore: new XsuaaSessionStore(['/path/to/sessions']),
356
- tokenProvider: new XsuaaTokenProvider(),
463
+ sessionStore: new XsuaaSessionStore('/path/to/sessions', 'https://mcp.example.com'),
464
+ // serviceKeyStore and tokenProvider not needed if session has UAA credentials
465
+ });
466
+
467
+ // XSUAA authentication - with service key initialization
468
+ const xsuaaBrokerWithServiceKey = new AuthBroker({
469
+ sessionStore: new XsuaaSessionStore('/path/to/sessions', 'https://mcp.example.com'),
470
+ serviceKeyStore: new XsuaaServiceKeyStore('/path/to/keys'),
471
+ // tokenProvider optional - direct UAA requests will be used
357
472
  }, 'none');
358
473
 
359
- // BTP authentication (browser or refresh token)
474
+ // BTP authentication - session only (direct UAA requests)
360
475
  const btpBroker = new AuthBroker({
361
- serviceKeyStore: new AbapServiceKeyStore(['/path/to/keys']),
362
- sessionStore: new BtpSessionStore(['/path/to/sessions']),
363
- tokenProvider: new BtpTokenProvider(),
476
+ sessionStore: new BtpSessionStore('/path/to/sessions', 'https://abap.example.com'),
477
+ // serviceKeyStore and tokenProvider not needed if session has UAA credentials
478
+ });
479
+
480
+ // BTP authentication - with service key and provider (for browser auth)
481
+ const btpBrokerFull = new AuthBroker({
482
+ sessionStore: new BtpSessionStore('/path/to/sessions', 'https://abap.example.com'),
483
+ serviceKeyStore: new AbapServiceKeyStore('/path/to/keys'),
484
+ tokenProvider: new BtpTokenProvider(), // needed for browser authentication
364
485
  });
365
486
  ```
366
487
 
488
+ ### Direct UAA HTTP Requests
489
+
490
+ When UAA credentials are available in session, `AuthBroker` automatically uses direct HTTP requests to UAA without requiring `tokenProvider`:
491
+
492
+ - **Refresh Token Grant**: Direct HTTP POST to `{uaaUrl}/oauth/token` with `grant_type=refresh_token`
493
+ - **Client Credentials Grant**: Direct HTTP POST to `{uaaUrl}/oauth/token` with `grant_type=client_credentials`
494
+
495
+ **Benefits:**
496
+ - No dependency on `tokenProvider` when session has UAA credentials
497
+ - Faster token refresh (no provider overhead)
498
+ - Simpler configuration (only `sessionStore` needed)
499
+
500
+ **Fallback to Provider:**
501
+ - If direct UAA request fails and `tokenProvider` is available, broker automatically falls back to provider
502
+ - Provider is useful for browser authentication or alternative authentication flows
503
+
367
504
  ### Utility Script
368
505
 
369
506
  Generate `.env` files from service keys:
@@ -5,8 +5,16 @@ import { ILogger } from '@mcp-abap-adt/interfaces';
5
5
  import { IServiceKeyStore, ISessionStore, IAuthorizationConfig, IConnectionConfig } from './stores/interfaces';
6
6
  import { ITokenProvider } from './providers';
7
7
  /**
8
- * AuthBroker manages JWT authentication tokens for destinations
8
+ * Configuration object for AuthBroker constructor
9
9
  */
10
+ export interface AuthBrokerConfig {
11
+ /** Session store (required) - stores and retrieves session data */
12
+ sessionStore: ISessionStore;
13
+ /** Service key store (optional) - stores and retrieves service keys */
14
+ serviceKeyStore?: IServiceKeyStore;
15
+ /** Token provider (optional) - handles token refresh and authentication flows. If not provided, direct UAA HTTP requests will be used when UAA credentials are available */
16
+ tokenProvider?: ITokenProvider;
17
+ }
10
18
  export declare class AuthBroker {
11
19
  private browser;
12
20
  private logger;
@@ -15,57 +23,71 @@ export declare class AuthBroker {
15
23
  private tokenProvider;
16
24
  /**
17
25
  * Create a new AuthBroker instance
18
- * @param stores Object with stores and token provider
19
- * - serviceKeyStore: Store for service keys
20
- * - sessionStore: Store for session data
21
- * - tokenProvider: Token provider implementing ITokenProvider interface
26
+ * @param config Configuration object with stores and token provider
27
+ * - sessionStore: Store for session data (required)
28
+ * - serviceKeyStore: Store for service keys (optional)
29
+ * - tokenProvider: Token provider implementing ITokenProvider interface (optional). If not provided, direct UAA HTTP requests will be used when UAA credentials are available
22
30
  * @param browser Optional browser name for authentication (chrome, edge, firefox, system, none).
23
31
  * Default: 'system' (system default browser).
24
32
  * Use 'none' to print URL instead of opening browser.
25
33
  * @param logger Optional logger instance implementing ILogger interface. If not provided, uses no-op logger.
26
34
  */
27
- constructor(stores: {
28
- serviceKeyStore: IServiceKeyStore;
29
- sessionStore: ISessionStore;
30
- tokenProvider: ITokenProvider;
31
- }, browser?: string, logger?: ILogger);
35
+ constructor(config: AuthBrokerConfig, browser?: string, logger?: ILogger);
36
+ /**
37
+ * Refresh token using refresh_token grant type (direct UAA HTTP request)
38
+ * @param refreshToken Refresh token
39
+ * @param authConfig UAA authorization configuration
40
+ * @returns Promise that resolves to new tokens
41
+ */
42
+ private refreshTokenDirect;
43
+ /**
44
+ * Get token using client_credentials grant type (direct UAA HTTP request)
45
+ * @param authConfig UAA authorization configuration
46
+ * @returns Promise that resolves to access token
47
+ */
48
+ private getTokenWithClientCredentials;
32
49
  /**
33
50
  * Get authentication token for destination.
34
- * Tries to load from session store, validates it, and refreshes if needed using a fallback chain.
35
- *
36
- * **Fallback Chain:**
37
- * 1. **Check session**: Load token from session store and validate it
38
- * - If token is valid, return it immediately
39
- * - If token is invalid or missing, continue to next step
40
- *
41
- * 2. **Check service key**: Verify that service key exists
42
- * - If no service key found, throw error
43
- *
44
- * 3. **Try refresh token**: If refresh token is available in session, attempt to refresh using it (via tokenProvider)
45
- * - If successful, save new token to session and return it
46
- * - If failed, continue to next step
51
+ * Implements a three-step flow: Step 0 (initialize), Step 1 (refresh), Step 2 (UAA).
47
52
  *
48
- * 4. **Try UAA (client_credentials)**: Attempt to get token using UAA credentials (via tokenProvider)
49
- * - If UAA parameters are available and authentication succeeds, save token to session and return it
50
- * - If failed or parameters missing, continue to next step
53
+ * **Flow:**
54
+ * **Step 0: Initialize Session with Token (if needed)**
55
+ * - Check if session has `authorizationToken` AND UAA credentials
56
+ * - If both are empty AND serviceKeyStore is available:
57
+ * - Try direct UAA request from service key (if UAA credentials available)
58
+ * - If failed and tokenProvider available → use provider
59
+ * - If session has token OR UAA credentials → proceed to Step 1
51
60
  *
52
- * 5. **Try browser authentication**: Attempt browser-based OAuth2 flow using service key (via tokenProvider)
53
- * - If successful, save token and refresh token to session and return it
54
- * - If failed, continue to next step
61
+ * **Step 1: Refresh Token Flow**
62
+ * - Check if refresh token exists in session
63
+ * - If refresh token exists:
64
+ * - Try direct UAA refresh (if UAA credentials in session)
65
+ * - If failed and tokenProvider available → use provider
66
+ * - If successful → return new token
67
+ * - Otherwise → proceed to Step 2
55
68
  *
56
- * 6. **Throw error**: If all authentication methods failed, throw comprehensive error with details
69
+ * **Step 2: UAA Credentials Flow**
70
+ * - Check if UAA credentials exist in session or service key
71
+ * - Try direct UAA client_credentials request (if UAA credentials available)
72
+ * - If failed and tokenProvider available → use provider
73
+ * - If successful → return new token
74
+ * - If all failed → return error
57
75
  *
58
- * **Note**: Token validation is performed only when checking existing session (step 1).
59
- * Tokens obtained through refresh/UAA/browser authentication are not validated before being saved.
76
+ * **Important Notes:**
77
+ * - If sessionStore contains valid UAA credentials, neither serviceKeyStore nor tokenProvider are required.
78
+ * Direct UAA HTTP requests will be used automatically.
79
+ * - tokenProvider is only needed when:
80
+ * - Initializing session from service key via browser authentication (Step 0)
81
+ * - Direct UAA requests fail and fallback to provider is needed
60
82
  *
61
83
  * @param destination Destination name (e.g., "TRIAL")
62
84
  * @returns Promise that resolves to JWT token string
63
- * @throws Error if neither session data nor service key found, or if all authentication methods failed
85
+ * @throws Error if session initialization fails or all authentication methods failed
64
86
  */
65
87
  getToken(destination: string): Promise<string>;
66
88
  /**
67
- * Force refresh token for destination using service key.
68
- * If no refresh token exists, starts browser authentication flow.
89
+ * Force refresh token for destination.
90
+ * Uses refresh token from session if available, otherwise uses UAA credentials from session or service key.
69
91
  * @param destination Destination name (e.g., "TRIAL")
70
92
  * @returns Promise that resolves to new JWT token string
71
93
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAY7C;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,aAAa,CAAiB;IAEtC;;;;;;;;;;OAUG;gBAED,MAAM,EAAE;QAAE,eAAe,EAAE,gBAAgB,CAAC;QAAC,YAAY,EAAE,aAAa,CAAC;QAAC,aAAa,EAAE,cAAc,CAAA;KAAE,EACzG,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO;IAuBlB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmIpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuCxD;;;;OAIG;IACG,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAWvF;;;;OAIG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAWlF"}
1
+ {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAW,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAa7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,YAAY,EAAE,aAAa,CAAC;IAC5B,uEAAuE;IACvE,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,4KAA4K;IAC5K,aAAa,CAAC,EAAE,cAAc,CAAC;CAChC;AAcD,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,CAA6B;IAElD;;;;;;;;;;OAUG;gBAED,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO;IAgElB;;;;;OAKG;YACW,kBAAkB;IA4ChC;;;;OAIG;YACW,6BAA6B;IA0C3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0SpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuFxD;;;;OAIG;IACG,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA2BvF;;;;OAIG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAyBlF"}