@mcp-abap-adt/auth-broker 0.1.5 → 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 (73) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/README.md +172 -15
  3. package/bin/generate-env-from-service-key.ts +128 -0
  4. package/dist/AuthBroker.d.ts +19 -29
  5. package/dist/AuthBroker.d.ts.map +1 -1
  6. package/dist/AuthBroker.js +86 -132
  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 -8
  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 -5
  20. package/dist/stores/index.d.ts.map +1 -1
  21. package/dist/stores/index.js +4 -8
  22. package/dist/stores/interfaces.d.ts +88 -22
  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 -136
  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/stores/SafeSessionStore.d.ts +0 -35
  63. package/dist/stores/SafeSessionStore.d.ts.map +0 -1
  64. package/dist/stores/SafeSessionStore.js +0 -42
  65. package/dist/tokenRefresher.d.ts +0 -17
  66. package/dist/tokenRefresher.d.ts.map +0 -1
  67. package/dist/tokenRefresher.js +0 -53
  68. package/dist/tokenStorage.d.ts +0 -15
  69. package/dist/tokenStorage.d.ts.map +0 -1
  70. package/dist/tokenStorage.js +0 -107
  71. package/dist/tokenValidator.d.ts +0 -11
  72. package/dist/tokenValidator.d.ts.map +0 -1
  73. package/dist/tokenValidator.js +0 -108
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Main AuthBroker class for managing JWT tokens based on destinations
3
3
  */
4
- import { Logger } from './logger';
5
- import { IServiceKeyStore, ISessionStore } 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
  */
@@ -11,19 +12,22 @@ export declare class AuthBroker {
11
12
  private logger;
12
13
  private serviceKeyStore;
13
14
  private sessionStore;
15
+ private tokenProvider;
14
16
  /**
15
17
  * Create a new AuthBroker instance
16
- * @param stores Object with custom stores. If not provided, creates default file-based stores.
17
- * - serviceKeyStore: Store for service keys (default: FileServiceKeyStore)
18
- * - sessionStore: Store for session data (default: FileSessionStore)
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
19
22
  * @param browser Optional browser name for authentication (chrome, edge, firefox, system, none).
20
23
  * Default: 'system' (system default browser).
21
24
  * Use 'none' to print URL instead of opening browser.
22
25
  * @param logger Optional logger instance. If not provided, uses default logger.
23
26
  */
24
- constructor(stores?: {
25
- serviceKeyStore?: IServiceKeyStore;
26
- sessionStore?: ISessionStore;
27
+ constructor(stores: {
28
+ serviceKeyStore: IServiceKeyStore;
29
+ sessionStore: ISessionStore;
30
+ tokenProvider: ITokenProvider;
27
31
  }, browser?: string, logger?: Logger);
28
32
  /**
29
33
  * Get authentication token for destination.
@@ -41,30 +45,16 @@ export declare class AuthBroker {
41
45
  */
42
46
  refreshToken(destination: string): Promise<string>;
43
47
  /**
44
- * Internal refresh token implementation
45
- * @private
46
- */
47
- private refreshTokenInternal;
48
- /**
49
- * Get SAP URL for destination.
50
- * Tries to load from session store first, then from service key store.
48
+ * Get authorization configuration for destination
51
49
  * @param destination Destination name (e.g., "TRIAL")
52
- * @returns Promise that resolves to SAP URL string, or undefined if not found
53
- */
54
- getSapUrl(destination: string): Promise<string | undefined>;
55
- /**
56
- * Clear cached token for specific destination
57
- * @param destination Destination name
50
+ * @returns Promise that resolves to IAuthorizationConfig or null if not found
58
51
  */
59
- clearCache(destination: string): void;
52
+ getAuthorizationConfig(destination: string): Promise<IAuthorizationConfig | null>;
60
53
  /**
61
- * Clear all cached tokens
62
- */
63
- clearAllCache(): void;
64
- /**
65
- * Get search paths for error messages (from file stores if available)
66
- * @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
67
57
  */
68
- private getSearchPathsForError;
58
+ getConnectionConfig(destination: string): Promise<IConnectionConfig | null>;
69
59
  }
70
60
  //# sourceMappingURL=AuthBroker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,EAAE,MAAM,EAAiB,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGtE;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,YAAY,CAAgB;IAEpC;;;;;;;;;OASG;gBAED,MAAM,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,gBAAgB,CAAC;QAAC,YAAY,CAAC,EAAE,aAAa,CAAA;KAAE,EAC7E,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM;IAQjB;;;;;;OAMG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiDpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBxD;;;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,12 +4,7 @@
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 logger_1 = require("./logger");
12
- const stores_1 = require("./stores");
7
+ const logger_1 = require("@mcp-abap-adt/logger");
13
8
  /**
14
9
  * AuthBroker manages JWT authentication tokens for destinations
15
10
  */
@@ -18,19 +13,22 @@ class AuthBroker {
18
13
  logger;
19
14
  serviceKeyStore;
20
15
  sessionStore;
16
+ tokenProvider;
21
17
  /**
22
18
  * Create a new AuthBroker instance
23
- * @param stores Object with custom stores. If not provided, creates default file-based stores.
24
- * - serviceKeyStore: Store for service keys (default: FileServiceKeyStore)
25
- * - sessionStore: Store for session data (default: FileSessionStore)
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
26
23
  * @param browser Optional browser name for authentication (chrome, edge, firefox, system, none).
27
24
  * Default: 'system' (system default browser).
28
25
  * Use 'none' to print URL instead of opening browser.
29
26
  * @param logger Optional logger instance. If not provided, uses default logger.
30
27
  */
31
28
  constructor(stores, browser, logger) {
32
- this.serviceKeyStore = stores?.serviceKeyStore || new stores_1.FileServiceKeyStore();
33
- this.sessionStore = stores?.sessionStore || new stores_1.FileSessionStore();
29
+ this.serviceKeyStore = stores.serviceKeyStore;
30
+ this.sessionStore = stores.sessionStore;
31
+ this.tokenProvider = stores.tokenProvider;
34
32
  this.browser = browser || 'system';
35
33
  this.logger = logger || logger_1.defaultLogger;
36
34
  }
@@ -42,47 +40,51 @@ class AuthBroker {
42
40
  * @throws Error if neither session data nor service key found
43
41
  */
44
42
  async getToken(destination) {
45
- // Check cache first
46
- const cachedToken = (0, cache_1.getCachedToken)(destination);
47
- if (cachedToken) {
48
- // Validate cached token
49
- const envConfig = await this.sessionStore.loadSession(destination);
50
- if (envConfig) {
51
- 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);
52
49
  if (isValid) {
53
- return cachedToken;
50
+ return connConfig.authorizationToken;
54
51
  }
55
- // Token expired, remove from cache
56
52
  }
57
- }
58
- // Load from session store
59
- const envConfig = await this.sessionStore.loadSession(destination);
60
- if (envConfig && envConfig.jwtToken) {
61
- // Validate token
62
- const isValid = await (0, tokenValidator_1.validateToken)(envConfig.jwtToken, envConfig.sapUrl);
63
- if (isValid) {
64
- (0, cache_1.setCachedToken)(destination, envConfig.jwtToken);
65
- return envConfig.jwtToken;
53
+ else {
54
+ // No service URL or provider doesn't support validation - just return token
55
+ return connConfig.authorizationToken;
66
56
  }
67
57
  }
68
- // 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
69
59
  const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
70
60
  if (!serviceKey) {
71
- // No service key and no valid token - throw error with helpful message
72
- const searchPaths = this.getSearchPathsForError();
73
- const searchedPaths = searchPaths.length > 0
74
- ? `\nSearched in:\n${searchPaths.map(p => ` - ${p}`).join('\n')}`
75
- : '';
61
+ // No service key and no valid token
76
62
  throw new Error(`No authentication found for destination "${destination}". ` +
77
- `Neither ${destination}.env file nor ${destination}.json service key found.\n` +
78
- `Please create one of:\n` +
79
- ` - ${destination}.env (with SAP_JWT_TOKEN)\n` +
80
- ` - ${destination}.json (service key)${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
+ });
81
86
  }
82
- // Try to refresh (will use browser auth if no refresh token)
83
- const newToken = await this.refreshTokenInternal(destination, serviceKey, envConfig);
84
- (0, cache_1.setCachedToken)(destination, newToken);
85
- return newToken;
87
+ return tokenResult.connectionConfig.authorizationToken;
86
88
  }
87
89
  /**
88
90
  * Force refresh token for destination using service key.
@@ -94,107 +96,59 @@ class AuthBroker {
94
96
  // Load service key
95
97
  const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
96
98
  if (!serviceKey) {
97
- const searchPaths = this.getSearchPathsForError();
98
- const searchedPaths = searchPaths.length > 0
99
- ? `\nSearched in:\n${searchPaths.map(p => ` - ${p}`).join('\n')}`
100
- : '';
101
- throw new Error(`Service key file not found for destination "${destination}".\n` +
102
- `Please create file: ${destination}.json${searchedPaths}`);
99
+ throw new Error(`Service key not found for destination "${destination}".`);
103
100
  }
104
- // Load existing session (for refresh token)
105
- const envConfig = await this.sessionStore.loadSession(destination);
106
- return this.refreshTokenInternal(destination, serviceKey, envConfig);
107
- }
108
- /**
109
- * Internal refresh token implementation
110
- * @private
111
- */
112
- async refreshTokenInternal(destination, serviceKey, envConfig) {
113
- // Extract UAA configuration
114
- const { url: uaaUrl, clientid: clientId, clientsecret: clientSecret } = serviceKey.uaa;
115
- if (!uaaUrl || !clientId || !clientSecret) {
116
- throw new Error(`Invalid service key for destination "${destination}". ` +
117
- `Missing required UAA fields: url, clientid, clientsecret`);
118
- }
119
- // Validate SAP URL early (before starting browser auth or refresh)
120
- const sapUrl = serviceKey.url || serviceKey.abap?.url || serviceKey.sap_url;
121
- if (!sapUrl) {
122
- throw new Error(`Service key for destination "${destination}" does not contain SAP URL. ` +
123
- `Expected field: url, abap.url, or sap_url`);
124
- }
125
- // Try to load existing refresh token from session store
126
- let refreshTokenValue = envConfig?.refreshToken;
127
- let result;
128
- // If no refresh token, start browser authentication flow
129
- if (!refreshTokenValue) {
130
- this.logger.debug(`No refresh token found for destination "${destination}". Starting browser authentication...`);
131
- result = await (0, browserAuth_1.startBrowserAuth)(serviceKey, this.browser || 'system', this.logger);
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`);
132
105
  }
133
- else {
134
- // Refresh token using refresh token
135
- result = await (0, tokenRefresher_1.refreshJwtToken)(refreshTokenValue, uaaUrl, clientId, clientSecret);
136
- }
137
- // Save new token to session store
138
- await this.sessionStore.saveSession(destination, {
139
- sapUrl,
140
- jwtToken: result.accessToken,
141
- refreshToken: result.refreshToken || refreshTokenValue,
142
- uaaUrl,
143
- uaaClientId: clientId,
144
- uaaClientSecret: clientSecret,
145
- sapClient: envConfig?.sapClient,
146
- 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,
147
113
  });
148
- // Update cache with new token
149
- (0, cache_1.setCachedToken)(destination, result.accessToken);
150
- 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;
151
124
  }
152
125
  /**
153
- * Get SAP URL for destination.
154
- * Tries to load from session store first, then from service key store.
126
+ * Get authorization configuration for destination
155
127
  * @param destination Destination name (e.g., "TRIAL")
156
- * @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
157
129
  */
158
- async getSapUrl(destination) {
159
- // Try to load from session store first
160
- const envConfig = await this.sessionStore.loadSession(destination);
161
- if (envConfig?.sapUrl) {
162
- return envConfig.sapUrl;
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;
163
135
  }
164
- // Try service key store
165
- const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
166
- if (serviceKey) {
167
- return serviceKey.url || serviceKey.abap?.url || serviceKey.sap_url;
168
- }
169
- return undefined;
170
- }
171
- /**
172
- * Clear cached token for specific destination
173
- * @param destination Destination name
174
- */
175
- clearCache(destination) {
176
- (0, cache_1.clearCache)(destination);
136
+ // Fall back to service key store (has UAA credentials)
137
+ return await this.serviceKeyStore.getAuthorizationConfig(destination);
177
138
  }
178
139
  /**
179
- * Clear all cached tokens
180
- */
181
- clearAllCache() {
182
- (0, cache_1.clearAllCache)();
183
- }
184
- /**
185
- * Get search paths for error messages (from file stores if available)
186
- * @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
187
143
  */
188
- getSearchPathsForError() {
189
- // Try to get search paths from file stores
190
- if (this.serviceKeyStore instanceof stores_1.FileServiceKeyStore) {
191
- return this.serviceKeyStore.getSearchPaths();
192
- }
193
- if (this.sessionStore instanceof stores_1.FileSessionStore) {
194
- 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;
195
149
  }
196
- // No file stores, return empty array
197
- return [];
150
+ // Fall back to service key store (has URLs but no tokens)
151
+ return await this.serviceKeyStore.getConnectionConfig(destination);
198
152
  }
199
153
  }
200
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 { IServiceKeyStore, ISessionStore, ServiceKeyStore, SessionStore } from './stores/interfaces';
9
- export { FileServiceKeyStore, FileSessionStore, SafeSessionStore } 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,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,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,13 +4,10 @@
4
4
  * JWT authentication broker for MCP ABAP ADT server
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.SafeSessionStore = 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; } });
16
- Object.defineProperty(exports, "SafeSessionStore", { enumerable: true, get: function () { return stores_1.SafeSessionStore; } });
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