@mcp-abap-adt/auth-stores 0.2.0 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.3] - 2025-12-16
11
+
12
+ ### Changed
13
+ - Dependency bump: `@mcp-abap-adt/interfaces` to `^0.1.17` for basic auth support
14
+
15
+ ### Added
16
+ - **Basic Authentication Support for On-Premise Systems**: Added support for basic auth (username/password) in addition to JWT tokens
17
+ - **envLoader.ts**: Now loads `SAP_USERNAME` and `SAP_PASSWORD` from `.env` files
18
+ - Automatically detects auth type: if username/password present and no JWT token, uses basic auth
19
+ - If JWT token present, uses JWT auth
20
+ - **AbapSessionStore.getConnectionConfig()**: Returns basic auth config when username/password are present
21
+ - Returns `IConnectionConfig` with `username`, `password`, and `authType: 'basic'` for on-premise systems
22
+ - Returns `IConnectionConfig` with `authorizationToken` and `authType: 'jwt'` for cloud systems
23
+ - **tokenStorage.ts**: Now saves `SAP_USERNAME` and `SAP_PASSWORD` to `.env` files
24
+ - Handles both JWT and basic auth configurations
25
+ - Clears username/password when JWT auth is used, and vice versa
26
+ - **constants.ts**: Added `USERNAME: 'SAP_USERNAME'` and `PASSWORD: 'SAP_PASSWORD'` to `ABAP_CONNECTION_VARS`
27
+ - This enables on-premise systems to use `--mcp` parameter with basic auth instead of requiring JWT tokens
28
+
29
+ ## [0.2.2] - 2025-12-13
30
+
31
+ ### Changed
32
+ - Dependency bump: `@mcp-abap-adt/interfaces` to `^0.1.16` for alignment with latest interfaces docs
33
+
34
+ ## [0.2.1] - 2025-12-12
35
+
36
+ ### Changed
37
+
38
+ - **Import Organization**: Reorganized imports across storage modules for consistency
39
+ - Moved `ILogger` type import after standard library imports (`fs`, `path`, `dotenv`)
40
+ - Affected files: `envLoader.ts`, `tokenStorage.ts`, `xsuaaEnvLoader.ts`, `xsuaaTokenStorage.ts`
41
+
42
+ ### Fixed
43
+
44
+ - **testLogger.ts**: Removed unused `ILogger` import
45
+
10
46
  ## [0.2.0] - 2025-12-08
11
47
 
12
48
  ### Breaking Changes
@@ -5,7 +5,10 @@ import type { ILogger } from '@mcp-abap-adt/interfaces';
5
5
  interface EnvConfig {
6
6
  sapUrl: string;
7
7
  sapClient?: string;
8
- jwtToken: string;
8
+ jwtToken?: string;
9
+ username?: string;
10
+ password?: string;
11
+ authType?: 'basic' | 'jwt';
9
12
  refreshToken?: string;
10
13
  uaaUrl?: string;
11
14
  uaaClientId?: string;
@@ -65,16 +65,38 @@ async function loadEnvFile(destination, directory, log) {
65
65
  // Extract required fields
66
66
  const sapUrl = parsed[constants_1.ABAP_CONNECTION_VARS.SERVICE_URL];
67
67
  const jwtToken = parsed[constants_1.ABAP_CONNECTION_VARS.AUTHORIZATION_TOKEN];
68
- log?.debug(`Extracted fields: hasSapUrl(${!!sapUrl}), hasJwtToken(${jwtToken !== undefined && jwtToken !== null})`);
69
- // sapUrl is required, jwtToken can be empty string (for authorization-only sessions)
70
- if (!sapUrl || jwtToken === undefined || jwtToken === null) {
71
- log?.warn(`Env file missing required fields: sapUrl(${!!sapUrl}), jwtToken(${jwtToken !== undefined && jwtToken !== null})`);
68
+ const username = parsed[constants_1.ABAP_CONNECTION_VARS.USERNAME];
69
+ const password = parsed[constants_1.ABAP_CONNECTION_VARS.PASSWORD];
70
+ log?.debug(`Extracted fields: hasSapUrl(${!!sapUrl}), hasJwtToken(${jwtToken !== undefined && jwtToken !== null}), hasUsername(${!!username}), hasPassword(${!!password})`);
71
+ // sapUrl is always required
72
+ if (!sapUrl) {
73
+ log?.warn(`Env file missing required field: sapUrl`);
72
74
  return null;
73
75
  }
76
+ // Determine auth type: if username/password present and no jwtToken, use basic auth
77
+ // If jwtToken present, use JWT auth
78
+ // If neither is present, it's OK - auth can be set later (e.g., via setAuthorizationConfig)
79
+ const isBasicAuth = !!(username && password) && (!jwtToken || jwtToken.trim() === '');
80
+ const isJwtAuth = !!(jwtToken && jwtToken.trim() !== '');
81
+ const hasNoAuth = !isBasicAuth && !isJwtAuth;
74
82
  const config = {
75
83
  sapUrl: sapUrl.trim(),
76
- jwtToken: jwtToken.trim(), // Can be empty string for authorization-only sessions
77
84
  };
85
+ // Set authentication fields based on type
86
+ if (isBasicAuth) {
87
+ config.username = username.trim();
88
+ config.password = password.trim();
89
+ config.authType = 'basic';
90
+ }
91
+ else if (isJwtAuth) {
92
+ config.jwtToken = jwtToken.trim();
93
+ config.authType = 'jwt';
94
+ }
95
+ else {
96
+ // No auth yet - will be set later (e.g., via setAuthorizationConfig)
97
+ config.jwtToken = jwtToken || '';
98
+ config.authType = undefined;
99
+ }
78
100
  // Optional fields
79
101
  if (parsed[constants_1.ABAP_CONNECTION_VARS.SAP_CLIENT]) {
80
102
  config.sapClient = parsed[constants_1.ABAP_CONNECTION_VARS.SAP_CLIENT].trim();
@@ -94,7 +116,11 @@ async function loadEnvFile(destination, directory, log) {
94
116
  if (parsed[constants_1.ABAP_CONNECTION_VARS.SAP_LANGUAGE]) {
95
117
  config.language = parsed[constants_1.ABAP_CONNECTION_VARS.SAP_LANGUAGE].trim();
96
118
  }
97
- log?.info(`Env config loaded from ${envFilePath}: sapUrl(${config.sapUrl.substring(0, 50)}...), token(${config.jwtToken.length} chars), hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl})`);
119
+ const tokenLength = config.jwtToken?.length || 0;
120
+ const authInfo = config.authType === 'basic'
121
+ ? `basic auth (username: ${config.username})`
122
+ : `JWT token(${tokenLength} chars)`;
123
+ log?.info(`Env config loaded from ${envFilePath}: sapUrl(${config.sapUrl.substring(0, 50)}...), ${authInfo}, hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl})`);
98
124
  return config;
99
125
  }
100
126
  catch (error) {
@@ -5,7 +5,10 @@ import type { ILogger } from '@mcp-abap-adt/interfaces';
5
5
  interface EnvConfig {
6
6
  sapUrl: string;
7
7
  sapClient?: string;
8
- jwtToken: string;
8
+ jwtToken?: string;
9
+ username?: string;
10
+ password?: string;
11
+ authType?: 'basic' | 'jwt';
9
12
  refreshToken?: string;
10
13
  uaaUrl?: string;
11
14
  uaaClientId?: string;
@@ -20,7 +23,7 @@ interface EnvConfig {
20
23
  * @param log Optional logger for logging operations
21
24
  */
22
25
  export declare function saveTokenToEnv(destination: string, savePath: string, config: Partial<EnvConfig> & {
23
- sapUrl?: string;
24
- jwtToken: string;
26
+ sapUrl: string;
27
+ jwtToken?: string;
25
28
  }, log?: ILogger): Promise<void>;
26
29
  export {};
@@ -51,7 +51,9 @@ async function saveTokenToEnv(destination, savePath, config, log) {
51
51
  const envFilePath = path.join(savePath, `${destination}.env`);
52
52
  const tempFilePath = `${envFilePath}.tmp`;
53
53
  log?.debug(`Saving token to env file: ${envFilePath}`);
54
- log?.debug(`Config to save: hasSapUrl(${!!config.sapUrl}), token(${config.jwtToken.length} chars), hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl})`);
54
+ const tokenLength = config.jwtToken?.length || 0;
55
+ const hasBasicAuth = !!(config.username && config.password);
56
+ log?.debug(`Config to save: hasSapUrl(${!!config.sapUrl}), token(${tokenLength} chars), hasBasicAuth(${hasBasicAuth}), hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl})`);
55
57
  // Ensure directory exists
56
58
  if (!fs.existsSync(savePath)) {
57
59
  log?.debug(`Creating directory: ${savePath}`);
@@ -83,10 +85,25 @@ async function saveTokenToEnv(destination, savePath, config, log) {
83
85
  }
84
86
  log?.debug(`Preserved ${existingVars.size} existing variables from env file`);
85
87
  // Update with new values
86
- if (config.sapUrl) {
87
- existingVars.set(constants_1.ABAP_CONNECTION_VARS.SERVICE_URL, config.sapUrl);
88
+ // sapUrl is required - always save it
89
+ existingVars.set(constants_1.ABAP_CONNECTION_VARS.SERVICE_URL, config.sapUrl);
90
+ // Handle authentication: JWT or basic auth
91
+ if (config.username && config.password) {
92
+ // Basic auth - save username/password
93
+ existingVars.set(constants_1.ABAP_CONNECTION_VARS.USERNAME, config.username);
94
+ existingVars.set(constants_1.ABAP_CONNECTION_VARS.PASSWORD, config.password);
95
+ // Clear JWT token if basic auth is used
96
+ if (config.jwtToken) {
97
+ existingVars.set(constants_1.ABAP_CONNECTION_VARS.AUTHORIZATION_TOKEN, '');
98
+ }
99
+ }
100
+ else if (config.jwtToken) {
101
+ // JWT auth - save token
102
+ existingVars.set(constants_1.ABAP_CONNECTION_VARS.AUTHORIZATION_TOKEN, config.jwtToken);
103
+ // Clear username/password if JWT auth is used
104
+ existingVars.delete(constants_1.ABAP_CONNECTION_VARS.USERNAME);
105
+ existingVars.delete(constants_1.ABAP_CONNECTION_VARS.PASSWORD);
88
106
  }
89
- existingVars.set(constants_1.ABAP_CONNECTION_VARS.AUTHORIZATION_TOKEN, config.jwtToken);
90
107
  if (config.sapClient) {
91
108
  existingVars.set(constants_1.ABAP_CONNECTION_VARS.SAP_CLIENT, config.sapClient);
92
109
  }
@@ -120,5 +137,8 @@ async function saveTokenToEnv(destination, savePath, config, log) {
120
137
  fs.writeFileSync(tempFilePath, envContent, 'utf8');
121
138
  // Atomic rename
122
139
  fs.renameSync(tempFilePath, envFilePath);
123
- log?.info(`Token saved to ${envFilePath}: token(${config.jwtToken.length} chars), sapUrl(${config.sapUrl ? config.sapUrl.substring(0, 50) + '...' : 'none'}), variables(${envLines.length})`);
140
+ const authInfo = hasBasicAuth
141
+ ? `basic auth (username: ${config.username})`
142
+ : `JWT token(${tokenLength} chars)`;
143
+ log?.info(`Token saved to ${envFilePath}: ${authInfo}, sapUrl(${config.sapUrl ? config.sapUrl.substring(0, 50) + '...' : 'none'}), variables(${envLines.length})`);
124
144
  }
@@ -94,9 +94,8 @@ class AbapSessionStore {
94
94
  convertToInternalFormat(config) {
95
95
  const obj = config;
96
96
  // Convert IConfig format (serviceUrl, authorizationToken) to internal format (sapUrl, jwtToken)
97
- return {
97
+ const result = {
98
98
  sapUrl: (obj.serviceUrl || obj.sapUrl),
99
- jwtToken: (obj.authorizationToken || obj.jwtToken || ''), // Ensure jwtToken is always a string
100
99
  refreshToken: obj.refreshToken,
101
100
  uaaUrl: obj.uaaUrl,
102
101
  uaaClientId: obj.uaaClientId,
@@ -104,6 +103,20 @@ class AbapSessionStore {
104
103
  sapClient: obj.sapClient,
105
104
  language: obj.language,
106
105
  };
106
+ // Handle authentication: JWT or basic auth
107
+ if (obj.username && obj.password) {
108
+ // Basic auth
109
+ result.username = obj.username;
110
+ result.password = obj.password;
111
+ result.authType = 'basic';
112
+ result.jwtToken = obj.authorizationToken || obj.jwtToken || '';
113
+ }
114
+ else {
115
+ // JWT auth
116
+ result.jwtToken = (obj.authorizationToken || obj.jwtToken || '');
117
+ result.authType = 'jwt';
118
+ }
119
+ return result;
107
120
  }
108
121
  /**
109
122
  * Save session to ENV file
@@ -125,6 +138,9 @@ class AbapSessionStore {
125
138
  await (0, tokenStorage_1.saveTokenToEnv)(destination, savePath, {
126
139
  sapUrl: abapConfig.sapUrl,
127
140
  jwtToken: abapConfig.jwtToken,
141
+ username: abapConfig.username,
142
+ password: abapConfig.password,
143
+ authType: abapConfig.authType,
128
144
  refreshToken: abapConfig.refreshToken,
129
145
  uaaUrl: abapConfig.uaaUrl,
130
146
  uaaClientId: abapConfig.uaaClientId,
@@ -193,6 +209,16 @@ class AbapSessionStore {
193
209
  if (rawSession.jwtToken !== undefined) {
194
210
  result.authorizationToken = rawSession.jwtToken;
195
211
  }
212
+ // Basic auth fields (if present)
213
+ if (rawSession.username) {
214
+ result.username = rawSession.username;
215
+ }
216
+ if (rawSession.password) {
217
+ result.password = rawSession.password;
218
+ }
219
+ if (rawSession.authType) {
220
+ result.authType = rawSession.authType;
221
+ }
196
222
  if (rawSession.sapClient) {
197
223
  result.sapClient = rawSession.sapClient;
198
224
  }
@@ -230,7 +256,7 @@ class AbapSessionStore {
230
256
  try {
231
257
  const raw = await this.loadFromFile(sessionPath);
232
258
  if (!raw || !isEnvConfig(raw)) {
233
- this.log?.debug(`Invalid session format for ${destination}: missing required fields (sapUrl, jwtToken)`);
259
+ this.log?.debug(`Invalid session format for ${destination}: missing required field (sapUrl)`);
234
260
  return null;
235
261
  }
236
262
  return raw;
@@ -276,14 +302,38 @@ class AbapSessionStore {
276
302
  this.log?.debug(`Connection config not found for ${destination}`);
277
303
  return null;
278
304
  }
279
- if (!sessionConfig.jwtToken || !sessionConfig.sapUrl) {
280
- this.log?.warn(`Connection config for ${destination} missing required fields: jwtToken(${!!sessionConfig.jwtToken}), sapUrl(${!!sessionConfig.sapUrl})`);
305
+ if (!sessionConfig.sapUrl) {
306
+ this.log?.warn(`Connection config for ${destination} missing required field: sapUrl`);
281
307
  return null;
282
308
  }
283
- this.log?.debug(`Connection config loaded for ${destination}: token(${sessionConfig.jwtToken.length} chars), sapUrl(${sessionConfig.sapUrl.substring(0, 40)}...)`);
309
+ // Check for basic auth: if username/password present and no jwtToken, use basic auth
310
+ const isBasicAuth = sessionConfig.authType === 'basic' ||
311
+ (!sessionConfig.jwtToken && sessionConfig.username && sessionConfig.password);
312
+ if (isBasicAuth) {
313
+ if (!sessionConfig.username || !sessionConfig.password) {
314
+ this.log?.warn(`Connection config for ${destination} missing required fields for basic auth: username(${!!sessionConfig.username}), password(${!!sessionConfig.password})`);
315
+ return null;
316
+ }
317
+ this.log?.debug(`Connection config loaded for ${destination} (basic auth): username(${sessionConfig.username}), sapUrl(${sessionConfig.sapUrl.substring(0, 40)}...)`);
318
+ return {
319
+ serviceUrl: sessionConfig.sapUrl,
320
+ username: sessionConfig.username,
321
+ password: sessionConfig.password,
322
+ authType: 'basic',
323
+ sapClient: sessionConfig.sapClient,
324
+ language: sessionConfig.language,
325
+ };
326
+ }
327
+ // JWT auth: check jwtToken
328
+ if (!sessionConfig.jwtToken) {
329
+ this.log?.warn(`Connection config for ${destination} missing required field for JWT auth: jwtToken`);
330
+ return null;
331
+ }
332
+ this.log?.debug(`Connection config loaded for ${destination} (JWT auth): token(${sessionConfig.jwtToken.length} chars), sapUrl(${sessionConfig.sapUrl.substring(0, 40)}...)`);
284
333
  return {
285
334
  serviceUrl: sessionConfig.sapUrl,
286
335
  authorizationToken: sessionConfig.jwtToken,
336
+ authType: 'jwt',
287
337
  sapClient: sessionConfig.sapClient,
288
338
  language: sessionConfig.language,
289
339
  };
@@ -298,10 +348,27 @@ class AbapSessionStore {
298
348
  async setAuthorizationConfig(destination, config) {
299
349
  const current = await this.loadRawSession(destination);
300
350
  if (!current) {
301
- // Session doesn't exist - try to get serviceUrl from connection config or use defaultServiceUrl
351
+ // Session doesn't exist - try to get serviceUrl from existing session file or use defaultServiceUrl
302
352
  // For ABAP, we need sapUrl to create session
303
- const connConfig = await this.getConnectionConfig(destination);
304
- const sapUrl = connConfig?.serviceUrl || this.defaultServiceUrl;
353
+ let sapUrl = this.defaultServiceUrl;
354
+ let existingAuthToken = '';
355
+ let existingUsername;
356
+ let existingPassword;
357
+ let existingAuthType;
358
+ // Try to load existing session file to get serviceUrl and auth info
359
+ try {
360
+ const existingSession = await this.loadSession(destination);
361
+ if (existingSession?.serviceUrl) {
362
+ sapUrl = existingSession.serviceUrl;
363
+ existingAuthToken = existingSession.authorizationToken || '';
364
+ existingUsername = existingSession?.username;
365
+ existingPassword = existingSession?.password;
366
+ existingAuthType = existingSession?.authType;
367
+ }
368
+ }
369
+ catch {
370
+ // Ignore errors when loading session - will use defaultServiceUrl
371
+ }
305
372
  if (!sapUrl) {
306
373
  this.log?.error(`Cannot set authorization config for ${destination}: session does not exist and serviceUrl is required. Missing defaultServiceUrl in constructor.`);
307
374
  throw new Error(`Cannot set authorization config for destination "${destination}": session does not exist and serviceUrl is required for ABAP sessions. Call setConnectionConfig first or provide defaultServiceUrl in constructor.`);
@@ -309,7 +376,10 @@ class AbapSessionStore {
309
376
  this.log?.debug(`Creating new session for ${destination} via setAuthorizationConfig: sapUrl(${sapUrl.substring(0, 40)}...)`);
310
377
  const newSession = {
311
378
  serviceUrl: sapUrl,
312
- authorizationToken: connConfig?.authorizationToken || '', // Use token from connection config if available
379
+ authorizationToken: existingAuthToken,
380
+ username: existingUsername,
381
+ password: existingPassword,
382
+ authType: existingAuthType,
313
383
  uaaUrl: config.uaaUrl,
314
384
  uaaClientId: config.uaaClientId,
315
385
  uaaClientSecret: config.uaaClientSecret,
@@ -387,5 +457,6 @@ function isEnvConfig(config) {
387
457
  if (!config || typeof config !== 'object')
388
458
  return false;
389
459
  const obj = config;
390
- return 'sapUrl' in obj && 'jwtToken' in obj;
460
+ // Must have sapUrl (authentication fields are optional - can be set later)
461
+ return 'sapUrl' in obj;
391
462
  }
@@ -55,6 +55,9 @@ class SafeAbapSessionStore {
55
55
  const internal = {
56
56
  sapUrl: (obj.serviceUrl || obj.sapUrl),
57
57
  jwtToken: (obj.authorizationToken || obj.jwtToken),
58
+ username: obj.username,
59
+ password: obj.password,
60
+ authType: obj.authType,
58
61
  refreshToken: obj.refreshToken,
59
62
  uaaUrl: obj.uaaUrl,
60
63
  uaaClientId: obj.uaaClientId,
@@ -130,14 +133,38 @@ class SafeAbapSessionStore {
130
133
  this.log?.debug(`Connection config not found for ${destination}`);
131
134
  return null;
132
135
  }
133
- if (!sessionConfig.jwtToken || !sessionConfig.sapUrl) {
134
- this.log?.warn(`Connection config for ${destination} missing required fields: jwtToken(${!!sessionConfig.jwtToken}), sapUrl(${!!sessionConfig.sapUrl})`);
136
+ if (!sessionConfig.sapUrl) {
137
+ this.log?.warn(`Connection config for ${destination} missing required field: sapUrl`);
135
138
  return null;
136
139
  }
137
- this.log?.debug(`Connection config loaded for ${destination}: token(${sessionConfig.jwtToken.length} chars), sapUrl(${sessionConfig.sapUrl.substring(0, 40)}...)`);
140
+ // Check for basic auth: if username/password present and no jwtToken, use basic auth
141
+ const isBasicAuth = sessionConfig.authType === 'basic' ||
142
+ (!sessionConfig.jwtToken && sessionConfig.username && sessionConfig.password);
143
+ if (isBasicAuth) {
144
+ if (!sessionConfig.username || !sessionConfig.password) {
145
+ this.log?.warn(`Connection config for ${destination} missing required fields for basic auth: username(${!!sessionConfig.username}), password(${!!sessionConfig.password})`);
146
+ return null;
147
+ }
148
+ this.log?.debug(`Connection config loaded for ${destination} (basic auth): username(${sessionConfig.username}), sapUrl(${sessionConfig.sapUrl.substring(0, 40)}...)`);
149
+ return {
150
+ serviceUrl: sessionConfig.sapUrl,
151
+ username: sessionConfig.username,
152
+ password: sessionConfig.password,
153
+ authType: 'basic',
154
+ sapClient: sessionConfig.sapClient,
155
+ language: sessionConfig.language,
156
+ };
157
+ }
158
+ // JWT auth: check jwtToken
159
+ if (!sessionConfig.jwtToken) {
160
+ this.log?.warn(`Connection config for ${destination} missing required field for JWT auth: jwtToken`);
161
+ return null;
162
+ }
163
+ this.log?.debug(`Connection config loaded for ${destination} (JWT auth): token(${sessionConfig.jwtToken.length} chars), sapUrl(${sessionConfig.sapUrl.substring(0, 40)}...)`);
138
164
  return {
139
165
  serviceUrl: sessionConfig.sapUrl,
140
166
  authorizationToken: sessionConfig.jwtToken,
167
+ authType: 'jwt',
141
168
  sapClient: sessionConfig.sapClient,
142
169
  language: sessionConfig.language,
143
170
  };
@@ -155,7 +182,10 @@ class SafeAbapSessionStore {
155
182
  this.log?.debug(`Creating new session for ${destination} via setConnectionConfig: serviceUrl(${serviceUrl.substring(0, 40)}...), token(${config.authorizationToken?.length || 0} chars)`);
156
183
  const newSession = {
157
184
  sapUrl: serviceUrl,
158
- jwtToken: config.authorizationToken || '',
185
+ jwtToken: config.authorizationToken,
186
+ username: config.username,
187
+ password: config.password,
188
+ authType: config.authType,
159
189
  sapClient: config.sapClient,
160
190
  language: config.language,
161
191
  };
@@ -168,7 +198,10 @@ class SafeAbapSessionStore {
168
198
  const updated = {
169
199
  ...current,
170
200
  sapUrl: config.serviceUrl || current.sapUrl,
171
- jwtToken: config.authorizationToken,
201
+ jwtToken: config.authorizationToken || current.jwtToken || '',
202
+ username: config.username !== undefined ? config.username : current.username,
203
+ password: config.password !== undefined ? config.password : current.password,
204
+ authType: config.authType !== undefined ? config.authType : current.authType,
172
205
  sapClient: config.sapClient !== undefined ? config.sapClient : current.sapClient,
173
206
  language: config.language !== undefined ? config.language : current.language,
174
207
  };
@@ -48,6 +48,10 @@ export declare const ABAP_CONNECTION_VARS: {
48
48
  readonly SERVICE_URL: "SAP_URL";
49
49
  /** Authorization token (JWT token) */
50
50
  readonly AUTHORIZATION_TOKEN: "SAP_JWT_TOKEN";
51
+ /** Username for basic authentication (on-premise systems) */
52
+ readonly USERNAME: "SAP_USERNAME";
53
+ /** Password for basic authentication (on-premise systems) */
54
+ readonly PASSWORD: "SAP_PASSWORD";
51
55
  /** SAP client number (optional) */
52
56
  readonly SAP_CLIENT: "SAP_CLIENT";
53
57
  /** Language (optional) */
@@ -51,6 +51,10 @@ exports.ABAP_CONNECTION_VARS = {
51
51
  SERVICE_URL: 'SAP_URL',
52
52
  /** Authorization token (JWT token) */
53
53
  AUTHORIZATION_TOKEN: 'SAP_JWT_TOKEN',
54
+ /** Username for basic authentication (on-premise systems) */
55
+ USERNAME: 'SAP_USERNAME',
56
+ /** Password for basic authentication (on-premise systems) */
57
+ PASSWORD: 'SAP_PASSWORD',
54
58
  /** SAP client number (optional) */
55
59
  SAP_CLIENT: 'SAP_CLIENT',
56
60
  /** Language (optional) */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/auth-stores",
3
- "version": "0.2.0",
3
+ "version": "0.2.3",
4
4
  "description": "Stores for MCP ABAP ADT auth-broker - BTP, ABAP, and XSUAA implementations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -49,7 +49,7 @@
49
49
  "node": ">=18.0.0"
50
50
  },
51
51
  "dependencies": {
52
- "@mcp-abap-adt/interfaces": "^0.1.4",
52
+ "@mcp-abap-adt/interfaces": "^0.1.17",
53
53
  "dotenv": "^17.2.1"
54
54
  },
55
55
  "devDependencies": {