@mcp-abap-adt/auth-broker 0.1.4 → 0.1.6

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +287 -0
  2. package/README.md +186 -9
  3. package/bin/generate-env-from-service-key.ts +128 -0
  4. package/dist/AuthBroker.d.ts +19 -35
  5. package/dist/AuthBroker.d.ts.map +1 -1
  6. package/dist/AuthBroker.js +87 -149
  7. package/dist/__tests__/helpers/configHelpers.d.ts +49 -0
  8. package/dist/__tests__/helpers/configHelpers.d.ts.map +1 -0
  9. package/dist/__tests__/helpers/configHelpers.js +169 -0
  10. package/dist/index.d.ts +4 -4
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +5 -7
  13. package/dist/providers/ITokenProvider.d.ts +49 -0
  14. package/dist/providers/ITokenProvider.d.ts.map +1 -0
  15. package/dist/providers/ITokenProvider.js +10 -0
  16. package/dist/providers/index.d.ts +8 -0
  17. package/dist/providers/index.d.ts.map +1 -0
  18. package/dist/providers/index.js +8 -0
  19. package/dist/stores/index.d.ts +5 -4
  20. package/dist/stores/index.d.ts.map +1 -1
  21. package/dist/stores/index.js +4 -6
  22. package/dist/stores/interfaces.d.ts +90 -20
  23. package/dist/stores/interfaces.d.ts.map +1 -1
  24. package/dist/stores/interfaces.js +1 -2
  25. package/dist/types.d.ts +7 -31
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/types.js +2 -0
  28. package/package.json +13 -6
  29. package/dist/__tests__/testHelpers.d.ts +0 -44
  30. package/dist/__tests__/testHelpers.d.ts.map +0 -1
  31. package/dist/__tests__/testHelpers.js +0 -129
  32. package/dist/browserAuth.d.ts +0 -17
  33. package/dist/browserAuth.d.ts.map +0 -1
  34. package/dist/browserAuth.js +0 -305
  35. package/dist/cache.d.ts +0 -20
  36. package/dist/cache.d.ts.map +0 -1
  37. package/dist/cache.js +0 -46
  38. package/dist/envLoader.d.ts +0 -12
  39. package/dist/envLoader.d.ts.map +0 -1
  40. package/dist/envLoader.js +0 -90
  41. package/dist/getToken.d.ts +0 -14
  42. package/dist/getToken.d.ts.map +0 -1
  43. package/dist/getToken.js +0 -62
  44. package/dist/logger.d.ts +0 -40
  45. package/dist/logger.d.ts.map +0 -1
  46. package/dist/logger.js +0 -186
  47. package/dist/pathResolver.d.ts +0 -21
  48. package/dist/pathResolver.d.ts.map +0 -1
  49. package/dist/pathResolver.js +0 -105
  50. package/dist/refreshToken.d.ts +0 -14
  51. package/dist/refreshToken.d.ts.map +0 -1
  52. package/dist/refreshToken.js +0 -71
  53. package/dist/serviceKeyLoader.d.ts +0 -12
  54. package/dist/serviceKeyLoader.d.ts.map +0 -1
  55. package/dist/serviceKeyLoader.js +0 -72
  56. package/dist/stores/FileServiceKeyStore.d.ts +0 -38
  57. package/dist/stores/FileServiceKeyStore.d.ts.map +0 -1
  58. package/dist/stores/FileServiceKeyStore.js +0 -47
  59. package/dist/stores/FileSessionStore.d.ts +0 -50
  60. package/dist/stores/FileSessionStore.d.ts.map +0 -1
  61. package/dist/stores/FileSessionStore.js +0 -116
  62. package/dist/tokenRefresher.d.ts +0 -17
  63. package/dist/tokenRefresher.d.ts.map +0 -1
  64. package/dist/tokenRefresher.js +0 -53
  65. package/dist/tokenStorage.d.ts +0 -15
  66. package/dist/tokenStorage.d.ts.map +0 -1
  67. package/dist/tokenStorage.js +0 -107
  68. package/dist/tokenValidator.d.ts +0 -11
  69. package/dist/tokenValidator.d.ts.map +0 -1
  70. package/dist/tokenValidator.js +0 -108
package/CHANGELOG.md CHANGED
@@ -9,6 +9,293 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the complete list.
11
11
 
12
+ ## [0.1.6] - 2025-01-XX
13
+
14
+ ### Changed
15
+ - **Package Split** - Extracted store and provider implementations into separate packages
16
+ - `@mcp-abap-adt/auth-stores-btp` - BTP and ABAP stores
17
+ - `@mcp-abap-adt/auth-stores-xsuaa` - XSUAA stores
18
+ - `@mcp-abap-adt/auth-providers` - XSUAA and BTP token providers
19
+ - `auth-broker` now only contains interfaces and core broker logic
20
+ - **ITokenProvider Interface** - Added optional `validateToken` method to token provider interface
21
+ - Token validation is now handled by providers, not by auth-broker
22
+ - Providers can implement custom validation logic
23
+ - **Dependencies** - Removed unused dependencies (axios, express, open, dotenv)
24
+ - These are now in provider/store packages
25
+ - `auth-broker` only depends on `@mcp-abap-adt/connection`
26
+
27
+ ### Removed
28
+ - Store implementations (moved to `@mcp-abap-adt/auth-stores-btp` and `@mcp-abap-adt/auth-stores-xsuaa`)
29
+ - Provider implementations (moved to `@mcp-abap-adt/auth-providers`)
30
+ - Token validator utility (moved to providers)
31
+ - Authentication functions (moved to providers)
32
+
33
+ ## [0.1.5] - 2025-12-03
34
+
35
+ ### Changed
36
+ - **Interface Naming** - All interfaces now start with `I` prefix
37
+ - `AuthorizationConfig` → `IAuthorizationConfig`
38
+ - `ConnectionConfig` → `IConnectionConfig`
39
+ - `ServiceKeyStore` → `IServiceKeyStore`
40
+ - `SessionStore` → `ISessionStore`
41
+ - **Type System** - Introduced `IConfig` as optional composition of `IAuthorizationConfig` and `IConnectionConfig`
42
+ - `loadSession()` and `getServiceKey()` now return `IConfig | null`
43
+ - `IConfig` is `Partial<IAuthorizationConfig> & Partial<IConnectionConfig>`
44
+ - **Token Provider Architecture** - Extracted token acquisition logic into `ITokenProvider` interface
45
+ - `XsuaaTokenProvider` - Uses client_credentials grant type (no browser)
46
+ - `BtpTokenProvider` - Uses browser-based OAuth2 or refresh token
47
+ - `AuthBroker` now accepts `tokenProvider` in constructor
48
+ - **XSUAA Configuration** - Renamed `btp_url` to `mcp_url` in YAML configuration
49
+ - For XSUAA, MCP URL is provided via `mcp_url` in YAML config (not `btp_url`)
50
+ - MCP URL is optional and not part of authentication
51
+ - **Constants** - Removed constants from exports (internal implementation details)
52
+ - All file operations are handled by stores through interfaces
53
+ - Consumers should use `IServiceKeyStore` and `ISessionStore` methods
54
+ - **File Structure** - Organized source code into logical subfolders
55
+ - `src/auth/` - Authentication logic (browserAuth, clientCredentialsAuth, tokenRefresher, tokenValidator)
56
+ - `src/cache/` - Token caching
57
+ - `src/constants/` - Internal constants
58
+ - `src/loaders/` - Service key loaders (abap, xsuaa)
59
+ - `src/logger/` - Logging utilities
60
+ - `src/methods/` - AuthBroker methods (getToken, refreshToken)
61
+ - `src/parsers/` - Service key parsers
62
+ - `src/pathResolver/` - Path resolution utilities
63
+ - `src/providers/` - Token providers (ITokenProvider, XsuaaTokenProvider, BtpTokenProvider)
64
+ - `src/storage/` - Environment file loaders and token storage (abap, btp, xsuaa)
65
+ - `src/stores/` - Store implementations (abap, btp, xsuaa)
66
+ - `src/types/` - Type definitions
67
+ - `src/utils/` - Utility functions
68
+ - **Test Structure** - Organized tests into subfolders by implementation
69
+ - `src/__tests__/broker/` - AuthBroker tests
70
+ - `src/__tests__/stores/abap/`, `src/__tests__/stores/btp/`, `src/__tests__/stores/xsuaa/` - Store tests
71
+ - `src/__tests__/loaders/abap/`, `src/__tests__/loaders/xsuaa/` - Loader tests
72
+ - `src/__tests__/storage/abap/`, `src/__tests__/storage/btp/`, `src/__tests__/storage/xsuaa/` - Storage tests
73
+ - `src/__tests__/parsers/` - Parser tests
74
+ - `src/__tests__/utils/` - Utility tests
75
+ - `src/__tests__/helpers/` - Test helpers (configHelpers, testHelpers, AuthBrokerTestHelper)
76
+
77
+ ### Removed
78
+ - **ServiceKey Type** - Removed `ServiceKey` type (internal implementation detail)
79
+ - **Internal Types** - Removed internal storage types from exports
80
+ - `EnvConfig`, `XsuaaSessionConfig`, `BtpSessionConfig` are now internal to store implementations
81
+ - **Constants Export** - Removed constants from public API
82
+ - `ABAP_AUTHORIZATION_VARS`, `ABAP_CONNECTION_VARS`, etc. are internal
83
+ - `ABAP_HEADERS`, `XSUAA_HEADERS`, `BTP_HEADERS` are internal
84
+ - **Parser Exports** - Removed parser interfaces and implementations from exports
85
+ - `IServiceKeyParser`, `AbapServiceKeyParser`, `XsuaaServiceKeyParser` are internal
86
+
87
+ ### Fixed
88
+ - **Test Configuration** - Tests now use YAML configuration file (`tests/test-config.yaml`)
89
+ - Removed hardcoded paths and destinations
90
+ - Added `AuthBrokerTestHelper` for creating broker instances from YAML
91
+ - Tests organized into subfolders by implementation (`abap`, `btp`, `xsuaa`)
92
+ - **Browser Authentication** - Fixed hanging tests when `browser: 'none'` is specified
93
+ - `startBrowserAuth` now immediately throws error with URL when `browser: 'none'`
94
+ - Added timeout to `clientCredentialsAuth` to prevent hanging
95
+ - **Session Store Validation** - Fixed validation in `Safe*SessionStore` classes
96
+ - Now accepts `IConfig` format (with `serviceUrl`/`authorizationToken`) and converts to internal format
97
+ - Validation messages updated to match actual error messages
98
+ - **YAML Configuration** - Fixed path resolution for test configuration
99
+ - Uses `findProjectRoot()` to reliably locate `test-config.yaml`
100
+ - Properly expands `~` to home directory in paths
101
+ - Added diagnostic logging controlled by `TEST_VERBOSE` environment variable
102
+
103
+ ### Added
104
+ - **BTP Full-Scope Authentication** - Full support for BTP authentication to ABAP systems (with full roles and scopes)
105
+ - `BtpSessionStore` - Store for BTP sessions (uses `BTP_*` environment variables)
106
+ - `SafeBtpSessionStore` - In-memory BTP session store
107
+ - `BtpSessionConfig` - Configuration interface for BTP authentication (includes `abapUrl`)
108
+ - `loadBtpEnvFile()` - Loads BTP session configuration from `.env` files with `BTP_*` variables
109
+ - `saveBtpTokenToEnv()` - Saves BTP session configuration to `.env` files with `BTP_*` variables
110
+ - **BTP Environment Variables** - `BTP_ENV_VARS` constants
111
+ - `BTP_ABAP_URL` - ABAP system URL (required, from service key or YAML)
112
+ - `BTP_JWT_TOKEN` - JWT token for `Authorization: Bearer` header
113
+ - `BTP_REFRESH_TOKEN` - Optional refresh token
114
+ - `BTP_UAA_URL`, `BTP_UAA_CLIENT_ID`, `BTP_UAA_CLIENT_SECRET` - UAA credentials (from service key)
115
+ - **BTP HTTP Headers** - `BTP_HEADERS` constants
116
+ - `BTP_HEADERS.AUTHORIZATION` - Authorization header
117
+ - `BTP_HEADERS.ABAP_URL` - ABAP URL header (`x-abap-url`)
118
+ - `BTP_HEADERS.BTP_DESTINATION` - BTP destination header (`x-btp-destination`)
119
+ - `BTP_HEADERS.SAP_CLIENT` - SAP client header (`x-sap-client`)
120
+ - `BTP_HEADERS.LANGUAGE` - Language header (`x-sap-language`)
121
+ - **Helper Functions** - `isBtpEnvVar()` function to check if environment variable is BTP-related
122
+ - **XSUAA Support** - Full support for XSUAA authentication (reduced scope)
123
+ - `XsuaaServiceKeyStore` - Store for XSUAA service keys (direct format from BTP)
124
+ - `XsuaaSessionStore` - Store for XSUAA sessions (uses `XSUAA_*` environment variables)
125
+ - `SafeXsuaaSessionStore` - In-memory XSUAA session store
126
+ - `XsuaaServiceKeyParser` - Parser for direct XSUAA service key format
127
+ - Client credentials grant type for XSUAA (no browser required)
128
+ - **Environment Variable Constants** - Exported constants for consumers
129
+ - `ABAP_ENV_VARS` - Environment variable names for ABAP connections (SAP_URL, SAP_JWT_TOKEN, etc.)
130
+ - `XSUAA_ENV_VARS` - Environment variable names for XSUAA connections (XSUAA_MCP_URL, XSUAA_JWT_TOKEN, etc.)
131
+ - `ABAP_HEADERS` - HTTP header names for ABAP requests (x-sap-url, x-sap-jwt-token, etc.)
132
+ - `XSUAA_HEADERS` - HTTP header names for XSUAA requests (Authorization, x-mcp-url, etc.)
133
+ - Helper functions: `getBtpAuthorizationHeader()`, `isAbapEnvVar()`, `isXsuaaEnvVar()`
134
+ - **Service Key Parsers** - Modular parser architecture
135
+ - `IServiceKeyParser` - Interface for service key parsers
136
+ - `AbapServiceKeyParser` - Parser for standard ABAP service keys
137
+ - `XsuaaServiceKeyParser` - Parser for direct XSUAA service keys
138
+ - **Utility Script** - `generate-env` command
139
+ - Generates `.env` files from service keys
140
+ - Supports both ABAP and XSUAA service key formats
141
+ - Automatically detects service key type and uses appropriate authentication flow
142
+ - **XSUAA Environment Loader** - `loadXsuaaEnvFile()` function
143
+ - Loads XSUAA session configuration from `.env` files with `XSUAA_*` variables
144
+ - **XSUAA Token Storage** - `saveXsuaaTokenToEnv()` function
145
+ - Saves XSUAA session configuration to `.env` files with `XSUAA_*` variables
146
+ - Automatically removes old `SAP_*` variables when saving XSUAA sessions
147
+
148
+ ### Changed
149
+ - **Interface Naming** - All interfaces now start with `I` prefix
150
+ - `AuthorizationConfig` → `IAuthorizationConfig`
151
+ - `ConnectionConfig` → `IConnectionConfig`
152
+ - `ServiceKeyStore` → `IServiceKeyStore`
153
+ - `SessionStore` → `ISessionStore`
154
+ - **Type System** - Introduced `IConfig` as optional composition of `IAuthorizationConfig` and `IConnectionConfig`
155
+ - `loadSession()` and `getServiceKey()` now return `IConfig | null`
156
+ - `IConfig` is `Partial<IAuthorizationConfig> & Partial<IConnectionConfig>`
157
+ - **Token Provider Architecture** - Extracted token acquisition logic into `ITokenProvider` interface
158
+ - `XsuaaTokenProvider` - Uses client_credentials grant type (no browser)
159
+ - `BtpTokenProvider` - Uses browser-based OAuth2 or refresh token
160
+ - `AuthBroker` now accepts `tokenProvider` in constructor
161
+ - **XSUAA Configuration** - Renamed `btp_url` to `mcp_url` in YAML configuration
162
+ - For XSUAA, MCP URL is provided via `mcp_url` in YAML config (not `btp_url`)
163
+ - MCP URL is optional and not part of authentication
164
+ - **Constants** - Removed constants from exports (internal implementation details)
165
+ - All file operations are handled by stores through interfaces
166
+ - Consumers should use `IServiceKeyStore` and `ISessionStore` methods
167
+ - **File Structure** - Organized source code into logical subfolders
168
+ - `src/auth/` - Authentication logic (browserAuth, clientCredentialsAuth, tokenRefresher, tokenValidator)
169
+ - `src/cache/` - Token caching
170
+ - `src/constants/` - Internal constants
171
+ - `src/loaders/` - Service key loaders (abap, xsuaa)
172
+ - `src/logger/` - Logging utilities
173
+ - `src/methods/` - AuthBroker methods (getToken, refreshToken)
174
+ - `src/parsers/` - Service key parsers
175
+ - `src/pathResolver/` - Path resolution utilities
176
+ - `src/providers/` - Token providers (ITokenProvider, XsuaaTokenProvider, BtpTokenProvider)
177
+ - `src/storage/` - Environment file loaders and token storage (abap, btp, xsuaa)
178
+ - `src/stores/` - Store implementations (abap, btp, xsuaa)
179
+ - `src/types/` - Type definitions
180
+ - `src/utils/` - Utility functions
181
+ - **Test Structure** - Organized tests into subfolders by implementation
182
+ - `src/__tests__/broker/` - AuthBroker tests
183
+ - `src/__tests__/stores/abap/`, `src/__tests__/stores/btp/`, `src/__tests__/stores/xsuaa/` - Store tests
184
+ - `src/__tests__/loaders/abap/`, `src/__tests__/loaders/xsuaa/` - Loader tests
185
+ - `src/__tests__/storage/abap/`, `src/__tests__/storage/btp/`, `src/__tests__/storage/xsuaa/` - Storage tests
186
+ - `src/__tests__/parsers/` - Parser tests
187
+ - `src/__tests__/utils/` - Utility tests
188
+ - `src/__tests__/helpers/` - Test helpers (configHelpers, testHelpers, AuthBrokerTestHelper)
189
+ - **Renamed XSUAA Components** - Clarified naming for reduced-scope XSUAA authentication
190
+ - `BtpSessionConfig` → `XsuaaSessionConfig` (for reduced-scope XSUAA)
191
+ - `BTP_ENV_VARS` → `XSUAA_ENV_VARS` (for reduced-scope XSUAA)
192
+ - `BTP_HEADERS` → `XSUAA_HEADERS` (for reduced-scope XSUAA)
193
+ - `BtpSessionStore` → `XsuaaSessionStore` (for reduced-scope XSUAA)
194
+ - `SafeBtpSessionStore` → `SafeXsuaaSessionStore` (for reduced-scope XSUAA)
195
+ - **XSUAA Session Format** - Uses `XSUAA_*` environment variables instead of `SAP_*`
196
+ - `XSUAA_MCP_URL` - MCP server URL (optional, not part of authentication)
197
+ - `XSUAA_JWT_TOKEN` - JWT token for `Authorization: Bearer` header
198
+ - `XSUAA_REFRESH_TOKEN` - Optional refresh token
199
+ - `XSUAA_UAA_URL`, `XSUAA_UAA_CLIENT_ID`, `XSUAA_UAA_CLIENT_SECRET` - UAA credentials
200
+ - **MCP URL Handling** - MCP URL is now optional for XSUAA sessions
201
+ - MCP URL is not part of authentication (only needed for making requests)
202
+ - Can be provided via YAML config (`mcp_url`), parameter, or request header
203
+ - Session files can be created without MCP URL (tokens and UAA credentials are sufficient)
204
+ - **Service Key URL Priority** - For XSUAA service keys, `apiurl` is prioritized over `url` for UAA authorization
205
+ - **Store Naming** - Renamed stores for clarity
206
+ - `FileServiceKeyStore` → `AbapServiceKeyStore` (for ABAP service keys)
207
+ - `FileSessionStore` → `AbapSessionStore` (for ABAP sessions)
208
+ - `SafeSessionStore` → `SafeAbapSessionStore` (for in-memory ABAP sessions)
209
+ - Old names still available as type aliases for backward compatibility
210
+
211
+ ### Removed
212
+ - **ServiceKey Type** - Removed `ServiceKey` type (internal implementation detail)
213
+ - **Internal Types** - Removed internal storage types from exports
214
+ - `EnvConfig`, `XsuaaSessionConfig`, `BtpSessionConfig` are now internal to store implementations
215
+ - **Constants Export** - Removed constants from public API
216
+ - `ABAP_AUTHORIZATION_VARS`, `ABAP_CONNECTION_VARS`, etc. are internal
217
+ - `ABAP_HEADERS`, `XSUAA_HEADERS`, `BTP_HEADERS` are internal
218
+ - **Parser Exports** - Removed parser interfaces and implementations from exports
219
+ - `IServiceKeyParser`, `AbapServiceKeyParser`, `XsuaaServiceKeyParser` are internal
220
+
221
+ ### Fixed
222
+ - **XSUAA Authentication** - Fixed client_credentials grant type implementation
223
+ - Uses POST request to UAA token endpoint with `grant_type=client_credentials`
224
+ - No browser interaction required for XSUAA
225
+ - Proper error handling for OAuth2 redirect parameters
226
+ - **Test Configuration** - Tests now use YAML configuration file (`tests/test-config.yaml`)
227
+ - Removed hardcoded paths and destinations
228
+ - Added `AuthBrokerTestHelper` for creating broker instances from YAML
229
+ - Tests organized into subfolders by implementation (`abap`, `btp`, `xsuaa`)
230
+ - **Browser Authentication** - Fixed hanging tests when `browser: 'none'` is specified
231
+ - `startBrowserAuth` now immediately throws error with URL when `browser: 'none'`
232
+ - Added timeout to `clientCredentialsAuth` to prevent hanging
233
+ - **Session Store Validation** - Fixed validation in `Safe*SessionStore` classes
234
+ - Now accepts `IConfig` format (with `serviceUrl`/`authorizationToken`) and converts to internal format
235
+ - Validation messages updated to match actual error messages
236
+ - **YAML Configuration** - Fixed path resolution for test configuration
237
+ - Uses `findProjectRoot()` to reliably locate `test-config.yaml`
238
+ - Properly expands `~` to home directory in paths
239
+ - Added diagnostic logging controlled by `TEST_VERBOSE` environment variable
240
+
241
+ ## [0.1.5] - 2025-12-02
242
+
243
+ ### Added
244
+ - **SafeSessionStore** - New in-memory session store implementation
245
+ - Stores session data in memory (Map) - data is lost after application restart
246
+ - Secure by default - doesn't persist sensitive data to disk
247
+ - Use when you want to ensure tokens are not saved to files
248
+ - Perfect for applications that require re-authentication after restart
249
+ - **SafeSessionStore Tests** - Comprehensive test coverage for SafeSessionStore
250
+ - Tests for `loadSession()` - loading non-existent, existing, and deleted sessions
251
+ - Tests for `saveSession()` - saving, overwriting, and multiple destinations
252
+ - Tests for `deleteSession()` - deleting existing and non-existent sessions
253
+ - Tests for in-memory behavior - data isolation between instances
254
+ - 11 test cases covering all functionality
255
+
256
+ ### Changed
257
+ - **Interface Naming** - Renamed interfaces for better readability
258
+ - `ServiceKeyStore` → `IServiceKeyStore` (new interface name)
259
+ - `SessionStore` → `ISessionStore` (new interface name)
260
+ - Old names still available as type aliases for backward compatibility
261
+ - All implementations updated to use new interface names
262
+ - **AuthBroker Constructor** - Simplified API
263
+ - Removed `searchPathsOrStores` parameter (string/array/object)
264
+ - Now accepts only `stores` object with `serviceKeyStore` and `sessionStore` properties
265
+ - Consumers must explicitly provide stores - no automatic path resolution
266
+ - Default stores: `FileServiceKeyStore()` and `FileSessionStore()` if not provided
267
+ - This change gives consumers full control over storage implementation
268
+
269
+ ### Breaking Changes
270
+ - **AuthBroker Constructor** - API change
271
+ - Old API: `new AuthBroker(searchPaths?: string | string[], browser?: string, logger?: Logger)`
272
+ - New API: `new AuthBroker(stores?: { serviceKeyStore?: IServiceKeyStore; sessionStore?: ISessionStore }, browser?: string, logger?: Logger)`
273
+ - Migration: Instead of passing paths, create stores explicitly:
274
+ ```typescript
275
+ // Old way (no longer works)
276
+ const broker = new AuthBroker(['/path/to/destinations']);
277
+
278
+ // New way
279
+ const { FileServiceKeyStore, FileSessionStore } = require('@mcp-abap-adt/auth-broker');
280
+ const broker = new AuthBroker({
281
+ serviceKeyStore: new FileServiceKeyStore(['/path/to/destinations']),
282
+ sessionStore: new FileSessionStore(['/path/to/destinations']),
283
+ });
284
+ ```
285
+
286
+ ### Fixed
287
+ - **Test Helpers** - Updated test helpers to use new AuthBroker API
288
+ - `testHelpers.ts` now uses `FileServiceKeyStore` and `FileSessionStore` with explicit paths
289
+ - All existing tests updated to work with new constructor signature
290
+ - Test coverage maintained at 100% for all components
291
+
292
+ ### Technical Details
293
+ - Consumers now have full control over storage implementation
294
+ - Can choose between `FileSessionStore` (persists to disk) and `SafeSessionStore` (in-memory)
295
+ - No automatic path resolution - consumers decide where to store files
296
+ - Better separation of concerns - storage logic is explicit
297
+ - All tests updated and passing (60 tests across 8 test suites)
298
+
12
299
  ## [0.1.4] - 2025-12-01
13
300
 
14
301
  ### Dependencies
package/README.md CHANGED
@@ -20,9 +20,30 @@ npm install @mcp-abap-adt/auth-broker
20
20
  ## Usage
21
21
 
22
22
  ```typescript
23
- import { AuthBroker } from '@mcp-abap-adt/auth-broker';
24
-
25
- const broker = new AuthBroker('/path/to/destinations', 'chrome');
23
+ import {
24
+ AuthBroker,
25
+ AbapServiceKeyStore,
26
+ AbapSessionStore,
27
+ SafeAbapSessionStore,
28
+ BtpTokenProvider
29
+ } from '@mcp-abap-adt/auth-broker';
30
+
31
+ // Use default file-based stores (current working directory)
32
+ const broker = new AuthBroker();
33
+
34
+ // Use custom file-based stores with specific paths
35
+ const broker = new AuthBroker({
36
+ serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']),
37
+ sessionStore: new AbapSessionStore(['/path/to/destinations']),
38
+ tokenProvider: new BtpTokenProvider(),
39
+ }, 'chrome');
40
+
41
+ // Use safe in-memory session store (data lost after restart)
42
+ const broker = new AuthBroker({
43
+ serviceKeyStore: new AbapServiceKeyStore(['/path/to/destinations']),
44
+ sessionStore: new SafeAbapSessionStore(), // In-memory, secure
45
+ tokenProvider: new BtpTokenProvider(),
46
+ });
26
47
 
27
48
  // Get token for destination (loads from .env, validates, refreshes if needed)
28
49
  const token = await broker.getToken('TRIAL');
@@ -40,7 +61,9 @@ const newToken = await broker.refreshToken('TRIAL');
40
61
 
41
62
  ### File Structure
42
63
 
43
- #### Environment File (`{destination}.env`)
64
+ #### Environment File for ABAP (`{destination}.env`)
65
+
66
+ For ABAP connections, use `SAP_*` environment variables:
44
67
 
45
68
  ```env
46
69
  SAP_URL=https://your-system.abap.us10.hana.ondemand.com
@@ -52,7 +75,41 @@ SAP_UAA_CLIENT_ID=client_id
52
75
  SAP_UAA_CLIENT_SECRET=client_secret
53
76
  ```
54
77
 
55
- #### Service Key File (`{destination}.json`)
78
+ #### Environment File for XSUAA (`{destination}.env`)
79
+
80
+ For XSUAA connections (reduced scope), use `XSUAA_*` environment variables:
81
+
82
+ ```env
83
+ XSUAA_MCP_URL=https://your-mcp-server.cfapps.eu10.hana.ondemand.com
84
+ XSUAA_JWT_TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
85
+ XSUAA_REFRESH_TOKEN=refresh_token_string
86
+ XSUAA_UAA_URL=https://your-account.authentication.eu10.hana.ondemand.com
87
+ XSUAA_UAA_CLIENT_ID=client_id
88
+ XSUAA_UAA_CLIENT_SECRET=client_secret
89
+ ```
90
+
91
+ **Note**: `XSUAA_MCP_URL` is optional - it's not part of authentication, only needed for making requests. The token and UAA credentials are sufficient for authentication.
92
+
93
+ #### Environment File for BTP (`{destination}.env`)
94
+
95
+ For BTP connections (full scope for ABAP systems), use `BTP_*` environment variables:
96
+
97
+ ```env
98
+ BTP_ABAP_URL=https://your-system.abap.us10.hana.ondemand.com
99
+ BTP_JWT_TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
100
+ BTP_REFRESH_TOKEN=refresh_token_string
101
+ BTP_UAA_URL=https://your-account.authentication.eu10.hana.ondemand.com
102
+ BTP_UAA_CLIENT_ID=client_id
103
+ BTP_UAA_CLIENT_SECRET=client_secret
104
+ BTP_SAP_CLIENT=100
105
+ BTP_LANGUAGE=EN
106
+ ```
107
+
108
+ **Note**: `BTP_ABAP_URL` is required - it's the ABAP system URL. All parameters (except tokens) come from service key.
109
+
110
+ #### Service Key File for ABAP (`{destination}.json`)
111
+
112
+ Standard ABAP service key format:
56
113
 
57
114
  ```json
58
115
  {
@@ -65,6 +122,41 @@ SAP_UAA_CLIENT_SECRET=client_secret
65
122
  }
66
123
  ```
67
124
 
125
+ #### Service Key File for XSUAA (`{destination}.json`)
126
+
127
+ Direct XSUAA service key format (from BTP):
128
+
129
+ ```json
130
+ {
131
+ "url": "https://your-account.authentication.eu10.hana.ondemand.com",
132
+ "apiurl": "https://api.authentication.eu10.hana.ondemand.com",
133
+ "clientid": "your_client_id",
134
+ "clientsecret": "your_client_secret"
135
+ }
136
+ ```
137
+
138
+ **Note**: For XSUAA service keys, `apiurl` is prioritized over `url` for UAA authorization if present.
139
+
140
+ ## XSUAA vs BTP Authentication
141
+
142
+ This package supports two types of BTP authentication:
143
+
144
+ ### XSUAA (Reduced Scope)
145
+ - **Purpose**: Access BTP services with limited scopes
146
+ - **Service Key**: Contains only UAA credentials (no ABAP URL)
147
+ - **Session Store**: `XsuaaSessionStore` (uses `XSUAA_*` environment variables)
148
+ - **Authentication**: Client credentials grant type (no browser required)
149
+ - **MCP URL**: Optional, provided separately (from YAML config `mcp_url`, parameter, or request header)
150
+ - **Use Case**: Accessing BTP services like MCP servers with reduced permissions
151
+
152
+ ### BTP (Full Scope for ABAP)
153
+ - **Purpose**: Access ABAP systems with full roles and scopes
154
+ - **Service Key**: Contains UAA credentials and ABAP URL
155
+ - **Session Store**: `BtpSessionStore` (uses `BTP_*` environment variables)
156
+ - **Authentication**: Browser-based OAuth2 (like ABAP) or refresh token
157
+ - **ABAP URL**: Required, from service key or YAML configuration
158
+ - **Use Case**: Accessing ABAP systems in BTP with full permissions
159
+
68
160
  ## API
69
161
 
70
162
  ### `AuthBroker`
@@ -72,11 +164,28 @@ SAP_UAA_CLIENT_SECRET=client_secret
72
164
  #### Constructor
73
165
 
74
166
  ```typescript
75
- new AuthBroker(searchPaths?: string | string[], browser?: string)
167
+ new AuthBroker(
168
+ stores?: {
169
+ serviceKeyStore?: IServiceKeyStore;
170
+ sessionStore?: ISessionStore;
171
+ tokenProvider?: ITokenProvider;
172
+ },
173
+ browser?: string,
174
+ logger?: Logger
175
+ )
76
176
  ```
77
177
 
78
- - `searchPaths` - Optional base directory or array of directories for searching `.env` and `.json` files
178
+ - `stores` - Optional object with custom storage implementations:
179
+ - `serviceKeyStore` - Store for service keys (default: `AbapServiceKeyStore()`)
180
+ - `sessionStore` - Store for session data (default: `AbapSessionStore()`)
181
+ - `tokenProvider` - Token provider for token acquisition (default: `BtpTokenProvider()`)
182
+ - Available implementations:
183
+ - **ABAP**: `AbapServiceKeyStore(searchPaths?)`, `AbapSessionStore(searchPaths?)`, `SafeAbapSessionStore()`, `BtpTokenProvider()`
184
+ - **XSUAA** (reduced scope): `XsuaaServiceKeyStore(searchPaths?)`, `XsuaaSessionStore(searchPaths?)`, `SafeXsuaaSessionStore()`, `XsuaaTokenProvider()`
185
+ - **BTP** (full scope for ABAP): `AbapServiceKeyStore(searchPaths?)`, `BtpSessionStore(searchPaths?)`, `SafeBtpSessionStore()`, `BtpTokenProvider()`
79
186
  - `browser` - Optional browser name for authentication (`chrome`, `edge`, `firefox`, `system`, `none`). Default: `system`
187
+ - For XSUAA, browser is not used (client_credentials grant type) - use `'none'`
188
+ - `logger` - Optional logger instance. If not provided, uses default logger
80
189
 
81
190
  #### Methods
82
191
 
@@ -96,6 +205,70 @@ Clear cached token for specific destination.
96
205
 
97
206
  Clear all cached tokens.
98
207
 
208
+ ### Token Providers
209
+
210
+ The package uses `ITokenProvider` interface for token acquisition. Two implementations are available:
211
+
212
+ - **`XsuaaTokenProvider`** - For XSUAA authentication (reduced scope)
213
+ - Uses client_credentials grant type
214
+ - No browser interaction required
215
+ - No refresh token provided
216
+
217
+ - **`BtpTokenProvider`** - For BTP/ABAP authentication (full scope)
218
+ - Uses browser-based OAuth2 flow (if no refresh token)
219
+ - Uses refresh token if available
220
+ - Provides refresh token for future use
221
+
222
+ **Example Usage:**
223
+
224
+ ```typescript
225
+ import {
226
+ AuthBroker,
227
+ XsuaaServiceKeyStore,
228
+ XsuaaSessionStore,
229
+ XsuaaTokenProvider,
230
+ BtpTokenProvider
231
+ } from '@mcp-abap-adt/auth-broker';
232
+
233
+ // XSUAA authentication (no browser needed)
234
+ const xsuaaBroker = new AuthBroker({
235
+ serviceKeyStore: new XsuaaServiceKeyStore(['/path/to/keys']),
236
+ sessionStore: new XsuaaSessionStore(['/path/to/sessions']),
237
+ tokenProvider: new XsuaaTokenProvider(),
238
+ }, 'none');
239
+
240
+ // BTP authentication (browser or refresh token)
241
+ const btpBroker = new AuthBroker({
242
+ serviceKeyStore: new AbapServiceKeyStore(['/path/to/keys']),
243
+ sessionStore: new BtpSessionStore(['/path/to/sessions']),
244
+ tokenProvider: new BtpTokenProvider(),
245
+ });
246
+ ```
247
+
248
+ ### Utility Script
249
+
250
+ Generate `.env` files from service keys:
251
+
252
+ ```bash
253
+ npm run generate-env <destination> [service-key-path] [session-path]
254
+ ```
255
+
256
+ **Examples:**
257
+ ```bash
258
+ # Generate .env from service key (auto-detect paths)
259
+ npm run generate-env mcp
260
+
261
+ # Specify paths explicitly
262
+ npm run generate-env mcp ./mcp.json ./mcp.env
263
+
264
+ # Use absolute paths
265
+ npm run generate-env TRIAL ~/.config/mcp-abap-adt/service-keys/TRIAL.json ~/.config/mcp-abap-adt/sessions/TRIAL.env
266
+ ```
267
+
268
+ The script automatically detects service key type (ABAP or XSUAA) and uses the appropriate authentication flow:
269
+ - **ABAP**: Opens browser for OAuth2 authorization code flow
270
+ - **XSUAA**: Uses client_credentials grant type (no browser required)
271
+
99
272
  ## Testing
100
273
 
101
274
  Tests are located in `src/__tests__/` and use Jest as the test runner.
@@ -140,9 +313,13 @@ Tests are designed to run sequentially (guaranteed by `maxWorkers: 1` and `maxCo
140
313
 
141
314
  ### Test Setup
142
315
 
143
- Place your service key file in `./test-destinations/TRIAL.json` to run tests 2 and 3.
316
+ 1. Copy `tests/test-config.yaml.template` to `tests/test-config.yaml`
317
+ 2. Fill in configuration values (paths, destinations, MCP URL for XSUAA)
318
+ 3. Place service key files in configured `service_keys_dir`:
319
+ - `{destination}.json` for ABAP tests (e.g., `trial.json`)
320
+ - `{btp_destination}.json` for XSUAA tests (e.g., `btp.json`)
144
321
 
145
- Tests will automatically skip if required files are missing or present when they shouldn't be.
322
+ Tests will automatically skip if required files are missing or configuration contains placeholders.
146
323
 
147
324
  ## Documentation
148
325
 
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Generate .env file from service key
4
+ *
5
+ * Usage:
6
+ * npm run generate-env <destination> [service-key-path] [session-path]
7
+ * or
8
+ * npx tsx bin/generate-env-from-service-key.ts <destination> [service-key-path] [session-path]
9
+ *
10
+ * Examples:
11
+ * npm run generate-env mcp
12
+ * npm run generate-env mcp ./mcp.json ./mcp.env
13
+ * npm run generate-env TRIAL ~/.config/mcp-abap-adt/service-keys/TRIAL.json
14
+ */
15
+
16
+ import * as path from 'path';
17
+ import * as fs from 'fs';
18
+ import { AuthBroker } from '../src/AuthBroker';
19
+ import { AbapServiceKeyStore, AbapSessionStore } from '@mcp-abap-adt/auth-stores-btp';
20
+ import { XsuaaServiceKeyStore, XsuaaSessionStore } from '@mcp-abap-adt/auth-stores-xsuaa';
21
+ import { BtpTokenProvider, XsuaaTokenProvider } from '@mcp-abap-adt/auth-providers';
22
+
23
+ async function main() {
24
+ const args = process.argv.slice(2);
25
+
26
+ if (args.length === 0) {
27
+ console.error('Usage: generate-env-from-service-key <destination> [service-key-path] [session-path]');
28
+ console.error('');
29
+ console.error('Examples:');
30
+ console.error(' generate-env-from-service-key mcp');
31
+ console.error(' generate-env-from-service-key mcp ./mcp.json ./mcp.env');
32
+ console.error(' generate-env-from-service-key TRIAL ~/.config/mcp-abap-adt/service-keys/TRIAL.json');
33
+ process.exit(1);
34
+ }
35
+
36
+ const destination = args[0];
37
+ const serviceKeyPath = args[1] || path.join(process.cwd(), `${destination}.json`);
38
+ const sessionPath = args[2] || path.join(process.cwd(), `${destination}.env`);
39
+
40
+ // Resolve paths
41
+ const resolvedServiceKeyPath = path.resolve(serviceKeyPath);
42
+ const resolvedSessionPath = path.resolve(sessionPath);
43
+ const serviceKeyDir = path.dirname(resolvedServiceKeyPath);
44
+ const sessionDir = path.dirname(resolvedSessionPath);
45
+
46
+ // Check if service key file exists
47
+ if (!fs.existsSync(resolvedServiceKeyPath)) {
48
+ console.error(`❌ Service key file not found: ${resolvedServiceKeyPath}`);
49
+ process.exit(1);
50
+ }
51
+
52
+ console.log(`📁 Service key: ${resolvedServiceKeyPath}`);
53
+ console.log(`📁 Session file: ${resolvedSessionPath}`);
54
+
55
+ try {
56
+ // Load service key to determine type
57
+ const rawServiceKey = JSON.parse(fs.readFileSync(resolvedServiceKeyPath, 'utf8'));
58
+ const isXsuaa = rawServiceKey.url && rawServiceKey.url.includes('authentication') && !rawServiceKey.uaa;
59
+
60
+ // Create appropriate stores
61
+ const serviceKeyStore = isXsuaa
62
+ ? new XsuaaServiceKeyStore([serviceKeyDir])
63
+ : new AbapServiceKeyStore([serviceKeyDir]);
64
+
65
+ const sessionStore = isXsuaa
66
+ ? new XsuaaSessionStore([sessionDir])
67
+ : new AbapSessionStore([sessionDir]);
68
+
69
+ // Create token provider
70
+ const tokenProvider = isXsuaa
71
+ ? new XsuaaTokenProvider()
72
+ : new BtpTokenProvider();
73
+
74
+ // Create AuthBroker
75
+ // For ABAP, use 'system' browser (will open browser for auth)
76
+ // For XSUAA, browser doesn't matter (uses client_credentials)
77
+ const broker = new AuthBroker({
78
+ serviceKeyStore,
79
+ sessionStore,
80
+ tokenProvider,
81
+ }, isXsuaa ? 'none' : 'system');
82
+
83
+ console.log(`🔐 Getting token for destination "${destination}"...`);
84
+ if (isXsuaa) {
85
+ console.log(` Using client_credentials grant type (no browser required)`);
86
+ } else {
87
+ console.log(` Using browser authentication (browser will open)`);
88
+ }
89
+
90
+ // Get token (will use client_credentials for XSUAA or browser auth for ABAP)
91
+ const token = await broker.getToken(destination);
92
+
93
+ console.log(`✅ Token obtained successfully`);
94
+
95
+ // Check if session file was created
96
+ if (fs.existsSync(resolvedSessionPath)) {
97
+ console.log(`✅ Session file created: ${resolvedSessionPath}`);
98
+
99
+ // Show service URL if available
100
+ const connConfig = await broker.getConnectionConfig(destination);
101
+ if (connConfig?.serviceUrl) {
102
+ if (isXsuaa) {
103
+ console.log(`📁 MCP URL: ${connConfig.serviceUrl}`);
104
+ } else {
105
+ console.log(`📁 SAP URL: ${connConfig.serviceUrl}`);
106
+ }
107
+ } else if (isXsuaa) {
108
+ console.log(`💡 Note: MCP URL not set in session (optional for XSUAA).`);
109
+ console.log(` Provide MCP URL via YAML config, parameter, or request header when making requests.`);
110
+ }
111
+ } else {
112
+ console.log(`⚠️ Session file was not created. Token is cached in memory.`);
113
+ }
114
+
115
+ } catch (error: any) {
116
+ console.error(`❌ Error: ${error.message}`);
117
+ if (error.stack) {
118
+ console.error(error.stack);
119
+ }
120
+ process.exit(1);
121
+ }
122
+ }
123
+
124
+ main().catch((error) => {
125
+ console.error('Fatal error:', error);
126
+ process.exit(1);
127
+ });
128
+