@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
@@ -1,35 +1,33 @@
1
1
  /**
2
2
  * Main AuthBroker class for managing JWT tokens based on destinations
3
3
  */
4
- import { Logger } from './logger';
5
- import { ServiceKeyStore, SessionStore } from './stores/interfaces';
4
+ import { Logger } from '@mcp-abap-adt/logger';
5
+ import { IServiceKeyStore, ISessionStore, IAuthorizationConfig, IConnectionConfig } from './stores/interfaces';
6
+ import { ITokenProvider } from './providers';
6
7
  /**
7
8
  * AuthBroker manages JWT authentication tokens for destinations
8
9
  */
9
10
  export declare class AuthBroker {
10
- private searchPaths;
11
11
  private browser;
12
12
  private logger;
13
13
  private serviceKeyStore;
14
14
  private sessionStore;
15
+ private tokenProvider;
15
16
  /**
16
17
  * Create a new AuthBroker instance
17
- * @param searchPathsOrStores Optional search paths for .env and .json files (backward compatibility),
18
- * OR object with custom stores.
19
- * If string/array: creates default file-based stores with these paths.
20
- * If object: uses provided stores (searchPaths ignored).
21
- * Priority for searchPaths:
22
- * 1. Constructor parameter (highest)
23
- * 2. AUTH_BROKER_PATH environment variable (colon/semicolon-separated)
24
- * 3. Current working directory (lowest)
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
25
22
  * @param browser Optional browser name for authentication (chrome, edge, firefox, system, none).
26
23
  * Default: 'system' (system default browser).
27
24
  * Use 'none' to print URL instead of opening browser.
28
25
  * @param logger Optional logger instance. If not provided, uses default logger.
29
26
  */
30
- constructor(searchPathsOrStores?: string | string[] | {
31
- serviceKeyStore?: ServiceKeyStore;
32
- sessionStore?: SessionStore;
27
+ constructor(stores: {
28
+ serviceKeyStore: IServiceKeyStore;
29
+ sessionStore: ISessionStore;
30
+ tokenProvider: ITokenProvider;
33
31
  }, browser?: string, logger?: Logger);
34
32
  /**
35
33
  * Get authentication token for destination.
@@ -47,30 +45,16 @@ export declare class AuthBroker {
47
45
  */
48
46
  refreshToken(destination: string): Promise<string>;
49
47
  /**
50
- * Internal refresh token implementation
51
- * @private
52
- */
53
- private refreshTokenInternal;
54
- /**
55
- * Get SAP URL for destination.
56
- * Tries to load from session store first, then from service key store.
48
+ * Get authorization configuration for destination
57
49
  * @param destination Destination name (e.g., "TRIAL")
58
- * @returns Promise that resolves to SAP URL string, or undefined if not found
59
- */
60
- getSapUrl(destination: string): Promise<string | undefined>;
61
- /**
62
- * Clear cached token for specific destination
63
- * @param destination Destination name
50
+ * @returns Promise that resolves to IAuthorizationConfig or null if not found
64
51
  */
65
- clearCache(destination: string): void;
52
+ getAuthorizationConfig(destination: string): Promise<IAuthorizationConfig | null>;
66
53
  /**
67
- * Clear all cached tokens
68
- */
69
- clearAllCache(): void;
70
- /**
71
- * Get search paths for error messages (from file stores if available)
72
- * @private
54
+ * Get connection configuration for destination
55
+ * @param destination Destination name (e.g., "TRIAL")
56
+ * @returns Promise that resolves to IConnectionConfig or null if not found
73
57
  */
74
- private getSearchPathsForError;
58
+ getConnectionConfig(destination: string): Promise<IConnectionConfig | null>;
75
59
  }
76
60
  //# sourceMappingURL=AuthBroker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,MAAM,EAAiB,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGpE;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,YAAY,CAAe;IAEnC;;;;;;;;;;;;;;OAcG;gBAED,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG;QAAE,eAAe,CAAC,EAAE,eAAe,CAAC;QAAC,YAAY,CAAC,EAAE,YAAY,CAAA;KAAE,EAC5G,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM;IAmBjB;;;;;;OAMG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgDpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBxD;;;OAGG;YACW,oBAAoB;IAuDlC;;;;;OAKG;IACG,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiBjE;;;OAGG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;CAW/B"}
1
+ {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAiB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,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,MAAM;IASjB;;;;;;OAMG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwDpD;;;;;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"}
@@ -4,51 +4,31 @@
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AuthBroker = void 0;
7
- const tokenValidator_1 = require("./tokenValidator");
8
- const tokenRefresher_1 = require("./tokenRefresher");
9
- const browserAuth_1 = require("./browserAuth");
10
- const cache_1 = require("./cache");
11
- const pathResolver_1 = require("./pathResolver");
12
- const logger_1 = require("./logger");
13
- const stores_1 = require("./stores");
7
+ const logger_1 = require("@mcp-abap-adt/logger");
14
8
  /**
15
9
  * AuthBroker manages JWT authentication tokens for destinations
16
10
  */
17
11
  class AuthBroker {
18
- searchPaths;
19
12
  browser;
20
13
  logger;
21
14
  serviceKeyStore;
22
15
  sessionStore;
16
+ tokenProvider;
23
17
  /**
24
18
  * Create a new AuthBroker instance
25
- * @param searchPathsOrStores Optional search paths for .env and .json files (backward compatibility),
26
- * OR object with custom stores.
27
- * If string/array: creates default file-based stores with these paths.
28
- * If object: uses provided stores (searchPaths ignored).
29
- * Priority for searchPaths:
30
- * 1. Constructor parameter (highest)
31
- * 2. AUTH_BROKER_PATH environment variable (colon/semicolon-separated)
32
- * 3. Current working directory (lowest)
19
+ * @param stores Object with stores and token provider
20
+ * - serviceKeyStore: Store for service keys
21
+ * - sessionStore: Store for session data
22
+ * - tokenProvider: Token provider implementing ITokenProvider interface
33
23
  * @param browser Optional browser name for authentication (chrome, edge, firefox, system, none).
34
24
  * Default: 'system' (system default browser).
35
25
  * Use 'none' to print URL instead of opening browser.
36
26
  * @param logger Optional logger instance. If not provided, uses default logger.
37
27
  */
38
- constructor(searchPathsOrStores, browser, logger) {
39
- // Handle backward compatibility: if first param is string/array, treat as searchPaths
40
- if (typeof searchPathsOrStores === 'string' || Array.isArray(searchPathsOrStores) || searchPathsOrStores === undefined) {
41
- this.searchPaths = (0, pathResolver_1.resolveSearchPaths)(searchPathsOrStores);
42
- // Create default file-based stores
43
- this.serviceKeyStore = new stores_1.FileServiceKeyStore(this.searchPaths);
44
- this.sessionStore = new stores_1.FileSessionStore(this.searchPaths);
45
- }
46
- else {
47
- // New API: stores provided
48
- this.searchPaths = (0, pathResolver_1.resolveSearchPaths)(undefined); // Still resolve for backward compatibility in internal functions
49
- this.serviceKeyStore = searchPathsOrStores.serviceKeyStore || new stores_1.FileServiceKeyStore();
50
- this.sessionStore = searchPathsOrStores.sessionStore || new stores_1.FileSessionStore();
51
- }
28
+ constructor(stores, browser, logger) {
29
+ this.serviceKeyStore = stores.serviceKeyStore;
30
+ this.sessionStore = stores.sessionStore;
31
+ this.tokenProvider = stores.tokenProvider;
52
32
  this.browser = browser || 'system';
53
33
  this.logger = logger || logger_1.defaultLogger;
54
34
  }
@@ -60,46 +40,51 @@ class AuthBroker {
60
40
  * @throws Error if neither session data nor service key found
61
41
  */
62
42
  async getToken(destination) {
63
- // Check cache first
64
- const cachedToken = (0, cache_1.getCachedToken)(destination);
65
- if (cachedToken) {
66
- // Validate cached token
67
- const envConfig = await this.sessionStore.loadSession(destination);
68
- if (envConfig) {
69
- const isValid = await (0, tokenValidator_1.validateToken)(cachedToken, envConfig.sapUrl);
43
+ // Load connection config from session store
44
+ const connConfig = await this.sessionStore.getConnectionConfig(destination);
45
+ if (connConfig?.authorizationToken) {
46
+ // Validate token if provider supports validation and we have service URL
47
+ if (this.tokenProvider.validateToken && connConfig.serviceUrl) {
48
+ const isValid = await this.tokenProvider.validateToken(connConfig.authorizationToken, connConfig.serviceUrl);
70
49
  if (isValid) {
71
- return cachedToken;
50
+ return connConfig.authorizationToken;
72
51
  }
73
- // Token expired, remove from cache
74
52
  }
75
- }
76
- // Load from session store
77
- const envConfig = await this.sessionStore.loadSession(destination);
78
- if (envConfig && envConfig.jwtToken) {
79
- // Validate token
80
- const isValid = await (0, tokenValidator_1.validateToken)(envConfig.jwtToken, envConfig.sapUrl);
81
- if (isValid) {
82
- (0, cache_1.setCachedToken)(destination, envConfig.jwtToken);
83
- return envConfig.jwtToken;
53
+ else {
54
+ // No service URL or provider doesn't support validation - just return token
55
+ return connConfig.authorizationToken;
84
56
  }
85
57
  }
86
- // Token not found or expired, check if we have service key for browser auth
58
+ // Token not found or expired, check if we have service key
87
59
  const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
88
60
  if (!serviceKey) {
89
- // No service key and no valid token - throw error with helpful message
90
- const searchPaths = this.getSearchPathsForError();
91
- const searchedPaths = searchPaths.map(p => ` - ${p}`).join('\n');
61
+ // No service key and no valid token
92
62
  throw new Error(`No authentication found for destination "${destination}". ` +
93
- `Neither ${destination}.env file nor ${destination}.json service key found.\n` +
94
- `Please create one of:\n` +
95
- ` - ${destination}.env (with SAP_JWT_TOKEN)\n` +
96
- ` - ${destination}.json (service key)\n` +
97
- `Searched in:\n${searchedPaths}`);
63
+ `No session data and no service key found.`);
64
+ }
65
+ // Get authorization config from service key
66
+ const authConfig = await this.serviceKeyStore.getAuthorizationConfig(destination);
67
+ if (!authConfig) {
68
+ throw new Error(`Service key for destination "${destination}" does not contain UAA credentials`);
69
+ }
70
+ // Get refresh token from session
71
+ const sessionAuthConfig = await this.sessionStore.getAuthorizationConfig(destination);
72
+ const authConfigWithRefresh = { ...authConfig, refreshToken: sessionAuthConfig?.refreshToken || authConfig.refreshToken };
73
+ // Get connection config with token from provider
74
+ const tokenResult = await this.tokenProvider.getConnectionConfig(authConfigWithRefresh, {
75
+ browser: this.browser,
76
+ logger: this.logger,
77
+ });
78
+ // Update session with new token
79
+ await this.sessionStore.setConnectionConfig(destination, tokenResult.connectionConfig);
80
+ // Update authorization config with new refresh token if available
81
+ if (tokenResult.refreshToken) {
82
+ await this.sessionStore.setAuthorizationConfig(destination, {
83
+ ...authConfig,
84
+ refreshToken: tokenResult.refreshToken,
85
+ });
98
86
  }
99
- // Try to refresh (will use browser auth if no refresh token)
100
- const newToken = await this.refreshTokenInternal(destination, serviceKey, envConfig);
101
- (0, cache_1.setCachedToken)(destination, newToken);
102
- return newToken;
87
+ return tokenResult.connectionConfig.authorizationToken;
103
88
  }
104
89
  /**
105
90
  * Force refresh token for destination using service key.
@@ -111,106 +96,59 @@ class AuthBroker {
111
96
  // Load service key
112
97
  const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
113
98
  if (!serviceKey) {
114
- const searchPaths = this.getSearchPathsForError();
115
- const searchedPaths = searchPaths.map(p => ` - ${p}`).join('\n');
116
- throw new Error(`Service key file not found for destination "${destination}".\n` +
117
- `Please create file: ${destination}.json\n` +
118
- `Searched in:\n${searchedPaths}`);
119
- }
120
- // Load existing session (for refresh token)
121
- const envConfig = await this.sessionStore.loadSession(destination);
122
- return this.refreshTokenInternal(destination, serviceKey, envConfig);
123
- }
124
- /**
125
- * Internal refresh token implementation
126
- * @private
127
- */
128
- async refreshTokenInternal(destination, serviceKey, envConfig) {
129
- // Extract UAA configuration
130
- const { url: uaaUrl, clientid: clientId, clientsecret: clientSecret } = serviceKey.uaa;
131
- if (!uaaUrl || !clientId || !clientSecret) {
132
- throw new Error(`Invalid service key for destination "${destination}". ` +
133
- `Missing required UAA fields: url, clientid, clientsecret`);
134
- }
135
- // Validate SAP URL early (before starting browser auth or refresh)
136
- const sapUrl = serviceKey.url || serviceKey.abap?.url || serviceKey.sap_url;
137
- if (!sapUrl) {
138
- throw new Error(`Service key for destination "${destination}" does not contain SAP URL. ` +
139
- `Expected field: url, abap.url, or sap_url`);
140
- }
141
- // Try to load existing refresh token from session store
142
- let refreshTokenValue = envConfig?.refreshToken;
143
- let result;
144
- // If no refresh token, start browser authentication flow
145
- if (!refreshTokenValue) {
146
- this.logger.debug(`No refresh token found for destination "${destination}". Starting browser authentication...`);
147
- result = await (0, browserAuth_1.startBrowserAuth)(serviceKey, this.browser || 'system', this.logger);
99
+ throw new Error(`Service key not found for destination "${destination}".`);
148
100
  }
149
- else {
150
- // Refresh token using refresh token
151
- result = await (0, tokenRefresher_1.refreshJwtToken)(refreshTokenValue, uaaUrl, clientId, clientSecret);
101
+ // Get authorization config from service key
102
+ const authConfig = await this.serviceKeyStore.getAuthorizationConfig(destination);
103
+ if (!authConfig) {
104
+ throw new Error(`Service key for destination "${destination}" does not contain UAA credentials`);
152
105
  }
153
- // Save new token to session store
154
- await this.sessionStore.saveSession(destination, {
155
- sapUrl,
156
- jwtToken: result.accessToken,
157
- refreshToken: result.refreshToken || refreshTokenValue,
158
- uaaUrl,
159
- uaaClientId: clientId,
160
- uaaClientSecret: clientSecret,
161
- sapClient: envConfig?.sapClient,
162
- language: envConfig?.language,
106
+ // Get refresh token from session
107
+ const sessionAuthConfig = await this.sessionStore.getAuthorizationConfig(destination);
108
+ const authConfigWithRefresh = { ...authConfig, refreshToken: sessionAuthConfig?.refreshToken || authConfig.refreshToken };
109
+ // Get connection config with token from provider
110
+ const tokenResult = await this.tokenProvider.getConnectionConfig(authConfigWithRefresh, {
111
+ browser: this.browser,
112
+ logger: this.logger,
163
113
  });
164
- // Update cache with new token
165
- (0, cache_1.setCachedToken)(destination, result.accessToken);
166
- return result.accessToken;
114
+ // Update session with new token
115
+ await this.sessionStore.setConnectionConfig(destination, tokenResult.connectionConfig);
116
+ // Update authorization config with new refresh token if available
117
+ if (tokenResult.refreshToken) {
118
+ await this.sessionStore.setAuthorizationConfig(destination, {
119
+ ...authConfig,
120
+ refreshToken: tokenResult.refreshToken,
121
+ });
122
+ }
123
+ return tokenResult.connectionConfig.authorizationToken;
167
124
  }
168
125
  /**
169
- * Get SAP URL for destination.
170
- * Tries to load from session store first, then from service key store.
126
+ * Get authorization configuration for destination
171
127
  * @param destination Destination name (e.g., "TRIAL")
172
- * @returns Promise that resolves to SAP URL string, or undefined if not found
128
+ * @returns Promise that resolves to IAuthorizationConfig or null if not found
173
129
  */
174
- async getSapUrl(destination) {
175
- // Try to load from session store first
176
- const envConfig = await this.sessionStore.loadSession(destination);
177
- if (envConfig?.sapUrl) {
178
- return envConfig.sapUrl;
179
- }
180
- // Try service key store
181
- const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
182
- if (serviceKey) {
183
- return serviceKey.url || serviceKey.abap?.url || serviceKey.sap_url;
130
+ async getAuthorizationConfig(destination) {
131
+ // Try session store first (has tokens)
132
+ const sessionAuthConfig = await this.sessionStore.getAuthorizationConfig(destination);
133
+ if (sessionAuthConfig) {
134
+ return sessionAuthConfig;
184
135
  }
185
- return undefined;
186
- }
187
- /**
188
- * Clear cached token for specific destination
189
- * @param destination Destination name
190
- */
191
- clearCache(destination) {
192
- (0, cache_1.clearCache)(destination);
136
+ // Fall back to service key store (has UAA credentials)
137
+ return await this.serviceKeyStore.getAuthorizationConfig(destination);
193
138
  }
194
139
  /**
195
- * Clear all cached tokens
196
- */
197
- clearAllCache() {
198
- (0, cache_1.clearAllCache)();
199
- }
200
- /**
201
- * Get search paths for error messages (from file stores if available)
202
- * @private
140
+ * Get connection configuration for destination
141
+ * @param destination Destination name (e.g., "TRIAL")
142
+ * @returns Promise that resolves to IConnectionConfig or null if not found
203
143
  */
204
- getSearchPathsForError() {
205
- // Try to get search paths from file stores
206
- if (this.serviceKeyStore instanceof stores_1.FileServiceKeyStore) {
207
- return this.serviceKeyStore.getSearchPaths();
208
- }
209
- if (this.sessionStore instanceof stores_1.FileSessionStore) {
210
- return this.sessionStore.getSearchPaths();
144
+ async getConnectionConfig(destination) {
145
+ // Try session store first (has tokens and URLs)
146
+ const sessionConnConfig = await this.sessionStore.getConnectionConfig(destination);
147
+ if (sessionConnConfig) {
148
+ return sessionConnConfig;
211
149
  }
212
- // Fallback to stored searchPaths (for backward compatibility)
213
- return this.searchPaths;
150
+ // Fall back to service key store (has URLs but no tokens)
151
+ return await this.serviceKeyStore.getConnectionConfig(destination);
214
152
  }
215
153
  }
216
154
  exports.AuthBroker = AuthBroker;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Configuration helpers for auth-broker tests
3
+ * Loads test configuration from test-config.yaml
4
+ */
5
+ export interface TestConfig {
6
+ auth_broker?: {
7
+ paths?: {
8
+ service_keys_dir?: string;
9
+ sessions_dir?: string;
10
+ };
11
+ abap?: {
12
+ destination?: string;
13
+ };
14
+ xsuaa?: {
15
+ btp_destination?: string;
16
+ mcp_destination?: string;
17
+ mcp_url?: string;
18
+ };
19
+ };
20
+ }
21
+ /**
22
+ * Load test configuration from YAML
23
+ * Uses test-config.yaml from tests/ directory
24
+ */
25
+ export declare function loadTestConfig(): TestConfig;
26
+ /**
27
+ * Check if test config has real values (not placeholders)
28
+ */
29
+ export declare function hasRealConfig(config: TestConfig, section: 'abap' | 'xsuaa'): boolean;
30
+ /**
31
+ * Get ABAP destination from config
32
+ */
33
+ export declare function getAbapDestination(config?: TestConfig): string | null;
34
+ /**
35
+ * Get XSUAA destinations from config
36
+ */
37
+ export declare function getXsuaaDestinations(config?: TestConfig): {
38
+ btp_destination: string | null;
39
+ mcp_url: string | null;
40
+ };
41
+ /**
42
+ * Get service keys directory from config
43
+ */
44
+ export declare function getServiceKeysDir(config?: TestConfig): string | null;
45
+ /**
46
+ * Get sessions directory from config
47
+ */
48
+ export declare function getSessionsDir(config?: TestConfig): string | null;
49
+ //# sourceMappingURL=configHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configHelpers.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/configHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE;YACN,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC;QACF,IAAI,CAAC,EAAE;YACL,WAAW,CAAC,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,KAAK,CAAC,EAAE;YACN,eAAe,CAAC,EAAE,MAAM,CAAC;YACzB,eAAe,CAAC,EAAE,MAAM,CAAC;YACzB,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;KACH,CAAC;CACH;AAkBD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,CA6C3C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CA2BpF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAGrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG;IACzD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAOA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAGpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAGjE"}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration helpers for auth-broker tests
4
+ * Loads test configuration from test-config.yaml
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.loadTestConfig = loadTestConfig;
41
+ exports.hasRealConfig = hasRealConfig;
42
+ exports.getAbapDestination = getAbapDestination;
43
+ exports.getXsuaaDestinations = getXsuaaDestinations;
44
+ exports.getServiceKeysDir = getServiceKeysDir;
45
+ exports.getSessionsDir = getSessionsDir;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const yaml = __importStar(require("js-yaml"));
49
+ let cachedConfig = null;
50
+ /**
51
+ * Find project root directory by looking for package.json
52
+ */
53
+ function findProjectRoot() {
54
+ let currentDir = __dirname;
55
+ while (currentDir !== path.dirname(currentDir)) {
56
+ const packageJsonPath = path.join(currentDir, 'package.json');
57
+ if (fs.existsSync(packageJsonPath)) {
58
+ return currentDir;
59
+ }
60
+ currentDir = path.dirname(currentDir);
61
+ }
62
+ // Fallback to process.cwd() if package.json not found
63
+ return process.cwd();
64
+ }
65
+ /**
66
+ * Load test configuration from YAML
67
+ * Uses test-config.yaml from tests/ directory
68
+ */
69
+ function loadTestConfig() {
70
+ if (cachedConfig) {
71
+ return cachedConfig;
72
+ }
73
+ // Find project root and load from tests/test-config.yaml
74
+ const projectRoot = findProjectRoot();
75
+ const configPath = path.resolve(projectRoot, 'tests', 'test-config.yaml');
76
+ const templatePath = path.resolve(projectRoot, 'tests', 'test-config.yaml.template');
77
+ if (process.env.TEST_VERBOSE) {
78
+ console.log(`[configHelpers] Project root: ${projectRoot}`);
79
+ console.log(`[configHelpers] Config path: ${configPath}`);
80
+ console.log(`[configHelpers] Config exists: ${fs.existsSync(configPath)}`);
81
+ }
82
+ if (fs.existsSync(configPath)) {
83
+ try {
84
+ const configContent = fs.readFileSync(configPath, 'utf8');
85
+ cachedConfig = yaml.load(configContent) || {};
86
+ if (process.env.TEST_VERBOSE) {
87
+ console.log(`[configHelpers] Loaded config:`, JSON.stringify(cachedConfig, null, 2));
88
+ }
89
+ return cachedConfig;
90
+ }
91
+ catch (error) {
92
+ console.warn(`Failed to load test config from ${configPath}:`, error);
93
+ return {};
94
+ }
95
+ }
96
+ if (fs.existsSync(templatePath)) {
97
+ console.warn('⚠️ tests/test-config.yaml not found. Using template (all integration tests will be disabled).');
98
+ try {
99
+ const templateContent = fs.readFileSync(templatePath, 'utf8');
100
+ cachedConfig = yaml.load(templateContent) || {};
101
+ return cachedConfig;
102
+ }
103
+ catch (error) {
104
+ console.warn(`Failed to load test config template from ${templatePath}:`, error);
105
+ return {};
106
+ }
107
+ }
108
+ console.warn('⚠️ Test configuration files not found.');
109
+ console.warn('Please create tests/test-config.yaml with test parameters.');
110
+ return {};
111
+ }
112
+ /**
113
+ * Check if test config has real values (not placeholders)
114
+ */
115
+ function hasRealConfig(config, section) {
116
+ if (!config.auth_broker) {
117
+ return false;
118
+ }
119
+ if (section === 'abap') {
120
+ const abap = config.auth_broker.abap;
121
+ if (!abap?.destination) {
122
+ return false;
123
+ }
124
+ // Check if destination is not a placeholder
125
+ return !abap.destination.includes('<') && !abap.destination.includes('>');
126
+ }
127
+ if (section === 'xsuaa') {
128
+ const xsuaa = config.auth_broker.xsuaa;
129
+ if (!xsuaa?.btp_destination || !xsuaa?.mcp_url) {
130
+ return false;
131
+ }
132
+ // Check if values are not placeholders
133
+ return (!xsuaa.btp_destination.includes('<') &&
134
+ !xsuaa.mcp_url.includes('<'));
135
+ }
136
+ return false;
137
+ }
138
+ /**
139
+ * Get ABAP destination from config
140
+ */
141
+ function getAbapDestination(config) {
142
+ const cfg = config || loadTestConfig();
143
+ return cfg.auth_broker?.abap?.destination || null;
144
+ }
145
+ /**
146
+ * Get XSUAA destinations from config
147
+ */
148
+ function getXsuaaDestinations(config) {
149
+ const cfg = config || loadTestConfig();
150
+ const xsuaa = cfg.auth_broker?.xsuaa;
151
+ return {
152
+ btp_destination: xsuaa?.btp_destination || null,
153
+ mcp_url: xsuaa?.mcp_url || null,
154
+ };
155
+ }
156
+ /**
157
+ * Get service keys directory from config
158
+ */
159
+ function getServiceKeysDir(config) {
160
+ const cfg = config || loadTestConfig();
161
+ return cfg.auth_broker?.paths?.service_keys_dir || null;
162
+ }
163
+ /**
164
+ * Get sessions directory from config
165
+ */
166
+ function getSessionsDir(config) {
167
+ const cfg = config || loadTestConfig();
168
+ return cfg.auth_broker?.paths?.sessions_dir || null;
169
+ }
package/dist/index.d.ts CHANGED
@@ -3,8 +3,8 @@
3
3
  * JWT authentication broker for MCP ABAP ADT server
4
4
  */
5
5
  export { AuthBroker } from './AuthBroker';
6
- export type { EnvConfig, ServiceKey } from './types';
7
- export { resolveSearchPaths, findFileInPaths } from './pathResolver';
8
- export { ServiceKeyStore, SessionStore } from './stores/interfaces';
9
- export { FileServiceKeyStore, FileSessionStore } from './stores';
6
+ export type { IAuthorizationConfig, IConnectionConfig, IServiceKeyStore, ISessionStore } from './stores/interfaces';
7
+ export type { IConfig } from './types';
8
+ export type { ITokenProvider, TokenProviderOptions, TokenProviderResult } from './providers';
9
+ export type { Logger } from '@mcp-abap-adt/logger';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpH,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE7F,YAAY,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -4,12 +4,10 @@
4
4
  * JWT authentication broker for MCP ABAP ADT server
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.FileSessionStore = exports.FileServiceKeyStore = exports.findFileInPaths = exports.resolveSearchPaths = exports.AuthBroker = void 0;
7
+ exports.AuthBroker = void 0;
8
8
  var AuthBroker_1 = require("./AuthBroker");
9
9
  Object.defineProperty(exports, "AuthBroker", { enumerable: true, get: function () { return AuthBroker_1.AuthBroker; } });
10
- var pathResolver_1 = require("./pathResolver");
11
- Object.defineProperty(exports, "resolveSearchPaths", { enumerable: true, get: function () { return pathResolver_1.resolveSearchPaths; } });
12
- Object.defineProperty(exports, "findFileInPaths", { enumerable: true, get: function () { return pathResolver_1.findFileInPaths; } });
13
- var stores_1 = require("./stores");
14
- Object.defineProperty(exports, "FileServiceKeyStore", { enumerable: true, get: function () { return stores_1.FileServiceKeyStore; } });
15
- Object.defineProperty(exports, "FileSessionStore", { enumerable: true, get: function () { return stores_1.FileSessionStore; } });
10
+ // Store and provider implementations are in separate packages:
11
+ // - @mcp-abap-adt/auth-stores-btp - BTP and ABAP stores
12
+ // - @mcp-abap-adt/auth-stores-xsuaa - XSUAA stores
13
+ // - @mcp-abap-adt/auth-providers - XSUAA and BTP token providers