@mcp-abap-adt/auth-stores 0.2.7 → 0.2.9
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 +34 -0
- package/dist/index.d.ts +10 -13
- package/dist/index.js +32 -35
- package/dist/loaders/abap/serviceKeyLoader.js +3 -6
- package/dist/loaders/xsuaa/xsuaaServiceKeyLoader.js +2 -2
- package/dist/parsers/abap/AbapServiceKeyParser.d.ts +2 -2
- package/dist/parsers/abap/AbapServiceKeyParser.js +20 -7
- package/dist/parsers/xsuaa/XsuaaServiceKeyParser.d.ts +2 -2
- package/dist/parsers/xsuaa/XsuaaServiceKeyParser.js +24 -16
- package/dist/storage/abap/envLoader.js +7 -5
- package/dist/storage/abap/tokenStorage.js +4 -4
- package/dist/storage/xsuaa/xsuaaEnvLoader.js +14 -9
- package/dist/storage/xsuaa/xsuaaTokenStorage.js +12 -7
- package/dist/stores/abap/AbapServiceKeyStore.d.ts +1 -1
- package/dist/stores/abap/AbapServiceKeyStore.js +11 -6
- package/dist/stores/abap/AbapSessionStore.d.ts +1 -1
- package/dist/stores/abap/AbapSessionStore.js +33 -14
- package/dist/stores/abap/SafeAbapSessionStore.d.ts +1 -1
- package/dist/stores/abap/SafeAbapSessionStore.js +13 -7
- package/dist/stores/env/EnvFileSessionStore.d.ts +8 -3
- package/dist/stores/env/EnvFileSessionStore.js +107 -15
- package/dist/stores/xsuaa/SafeXsuaaSessionStore.d.ts +1 -1
- package/dist/stores/xsuaa/SafeXsuaaSessionStore.js +18 -10
- package/dist/stores/xsuaa/XsuaaServiceKeyStore.d.ts +1 -1
- package/dist/stores/xsuaa/XsuaaServiceKeyStore.js +10 -5
- package/dist/stores/xsuaa/XsuaaSessionStore.d.ts +1 -1
- package/dist/stores/xsuaa/XsuaaSessionStore.js +19 -12
- package/dist/utils/EnvFileHandler.js +5 -5
- package/dist/utils/JsonFileHandler.js +3 -3
- package/dist/utils/pathResolver.js +8 -5
- package/package.json +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.9] - 2025-12-22
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **Migrated to Biome**: Replaced ESLint/Prettier with Biome for linting and formatting
|
|
14
|
+
- Added `@biomejs/biome` as dev dependency (^2.3.10)
|
|
15
|
+
- Added `biome.json` configuration file with recommended rules
|
|
16
|
+
- Added npm scripts: `lint`, `lint:check`, `format`
|
|
17
|
+
- Updated `build` script to include Biome check before TypeScript compilation
|
|
18
|
+
- All code now follows Biome formatting and linting rules
|
|
19
|
+
- Updated Node.js imports to use `node:` protocol (fs, path, os)
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- **Type Safety Improvements**: Replaced `any` types with `unknown` for better type safety
|
|
23
|
+
- Parser methods (`canParse`, `parse`): Changed parameter types from `any` to `unknown` with proper type guards
|
|
24
|
+
- `AbapSessionStore`: Replaced `as any` casts with proper type intersections (`IConfig & Record<string, unknown>`)
|
|
25
|
+
- All parsers now use proper type guards to safely access object properties
|
|
26
|
+
- **Code Quality**: Improved code organization
|
|
27
|
+
- Organized imports automatically
|
|
28
|
+
- Fixed code formatting issues
|
|
29
|
+
- Improved type safety in session store operations
|
|
30
|
+
|
|
31
|
+
## [0.2.8] - 2025-12-21
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **EnvFileSessionStore**: File persistence for JWT tokens
|
|
35
|
+
- `save()` method writes `SAP_JWT_TOKEN` and `SAP_REFRESH_TOKEN` back to the .env file
|
|
36
|
+
- `setToken()`, `setRefreshToken()`, `setConnectionConfig()`, `setAuthorizationConfig()`, `saveSession()` now automatically persist JWT changes to file
|
|
37
|
+
- Enables token refresh flow to update the .env file with new tokens
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- **EnvFileSessionStore**: No longer "read-only" for JWT auth
|
|
41
|
+
- Basic auth credentials remain read-only (not written back)
|
|
42
|
+
- JWT tokens are persisted on update
|
|
43
|
+
|
|
10
44
|
## [0.2.7] - 2025-12-21
|
|
11
45
|
|
|
12
46
|
### Fixed
|
package/dist/index.d.ts
CHANGED
|
@@ -4,20 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Provides ABAP and XSUAA store implementations
|
|
6
6
|
*/
|
|
7
|
+
export { FileNotFoundError, InvalidConfigError, ParseError, StorageError, StoreError, } from './errors/StoreErrors';
|
|
8
|
+
export { loadServiceKey } from './loaders/abap/serviceKeyLoader';
|
|
9
|
+
export { loadXSUAAServiceKey } from './loaders/xsuaa/xsuaaServiceKeyLoader';
|
|
10
|
+
export { AbapServiceKeyStore } from './stores/abap/AbapServiceKeyStore';
|
|
7
11
|
export { AbapSessionStore } from './stores/abap/AbapSessionStore';
|
|
8
12
|
export { SafeAbapSessionStore } from './stores/abap/SafeAbapSessionStore';
|
|
9
|
-
export { AbapServiceKeyStore } from './stores/abap/AbapServiceKeyStore';
|
|
10
|
-
export { XsuaaSessionStore } from './stores/xsuaa/XsuaaSessionStore';
|
|
11
|
-
export { SafeXsuaaSessionStore } from './stores/xsuaa/SafeXsuaaSessionStore';
|
|
12
|
-
export { XsuaaServiceKeyStore } from './stores/xsuaa/XsuaaServiceKeyStore';
|
|
13
|
-
export { XsuaaSessionStore as BtpSessionStore } from './stores/xsuaa/XsuaaSessionStore';
|
|
14
|
-
export { SafeXsuaaSessionStore as SafeBtpSessionStore } from './stores/xsuaa/SafeXsuaaSessionStore';
|
|
15
|
-
export { XsuaaServiceKeyStore as BtpServiceKeyStore } from './stores/xsuaa/XsuaaServiceKeyStore';
|
|
16
13
|
export { EnvFileSessionStore } from './stores/env/EnvFileSessionStore';
|
|
17
|
-
export {
|
|
18
|
-
export {
|
|
19
|
-
export {
|
|
14
|
+
export { SafeXsuaaSessionStore, SafeXsuaaSessionStore as SafeBtpSessionStore, } from './stores/xsuaa/SafeXsuaaSessionStore';
|
|
15
|
+
export { XsuaaServiceKeyStore, XsuaaServiceKeyStore as BtpServiceKeyStore, } from './stores/xsuaa/XsuaaServiceKeyStore';
|
|
16
|
+
export { XsuaaSessionStore, XsuaaSessionStore as BtpSessionStore, } from './stores/xsuaa/XsuaaSessionStore';
|
|
17
|
+
export { ABAP_AUTHORIZATION_VARS, ABAP_CONNECTION_VARS, BTP_AUTHORIZATION_VARS, BTP_CONNECTION_VARS, XSUAA_AUTHORIZATION_VARS, XSUAA_CONNECTION_VARS, } from './utils/constants';
|
|
20
18
|
export { EnvFileHandler } from './utils/EnvFileHandler';
|
|
21
|
-
export {
|
|
22
|
-
export {
|
|
23
|
-
export { loadXSUAAServiceKey } from './loaders/xsuaa/xsuaaServiceKeyLoader';
|
|
19
|
+
export { JsonFileHandler } from './utils/JsonFileHandler';
|
|
20
|
+
export { findFileInPaths, resolveSearchPaths } from './utils/pathResolver';
|
package/dist/index.js
CHANGED
|
@@ -6,46 +6,40 @@
|
|
|
6
6
|
* Provides ABAP and XSUAA store implementations
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.resolveSearchPaths = exports.findFileInPaths = exports.JsonFileHandler = exports.EnvFileHandler = exports.XSUAA_CONNECTION_VARS = exports.XSUAA_AUTHORIZATION_VARS = exports.BTP_CONNECTION_VARS = exports.BTP_AUTHORIZATION_VARS = exports.ABAP_CONNECTION_VARS = exports.ABAP_AUTHORIZATION_VARS = exports.BtpSessionStore = exports.XsuaaSessionStore = exports.BtpServiceKeyStore = exports.XsuaaServiceKeyStore = exports.SafeBtpSessionStore = exports.SafeXsuaaSessionStore = exports.EnvFileSessionStore = exports.SafeAbapSessionStore = exports.AbapSessionStore = exports.AbapServiceKeyStore = exports.loadXSUAAServiceKey = exports.loadServiceKey = exports.StoreError = exports.StorageError = exports.ParseError = exports.InvalidConfigError = exports.FileNotFoundError = void 0;
|
|
10
|
+
// Error classes
|
|
11
|
+
var StoreErrors_1 = require("./errors/StoreErrors");
|
|
12
|
+
Object.defineProperty(exports, "FileNotFoundError", { enumerable: true, get: function () { return StoreErrors_1.FileNotFoundError; } });
|
|
13
|
+
Object.defineProperty(exports, "InvalidConfigError", { enumerable: true, get: function () { return StoreErrors_1.InvalidConfigError; } });
|
|
14
|
+
Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return StoreErrors_1.ParseError; } });
|
|
15
|
+
Object.defineProperty(exports, "StorageError", { enumerable: true, get: function () { return StoreErrors_1.StorageError; } });
|
|
16
|
+
Object.defineProperty(exports, "StoreError", { enumerable: true, get: function () { return StoreErrors_1.StoreError; } });
|
|
17
|
+
// Loaders
|
|
18
|
+
var serviceKeyLoader_1 = require("./loaders/abap/serviceKeyLoader");
|
|
19
|
+
Object.defineProperty(exports, "loadServiceKey", { enumerable: true, get: function () { return serviceKeyLoader_1.loadServiceKey; } });
|
|
20
|
+
var xsuaaServiceKeyLoader_1 = require("./loaders/xsuaa/xsuaaServiceKeyLoader");
|
|
21
|
+
Object.defineProperty(exports, "loadXSUAAServiceKey", { enumerable: true, get: function () { return xsuaaServiceKeyLoader_1.loadXSUAAServiceKey; } });
|
|
22
|
+
var AbapServiceKeyStore_1 = require("./stores/abap/AbapServiceKeyStore");
|
|
23
|
+
Object.defineProperty(exports, "AbapServiceKeyStore", { enumerable: true, get: function () { return AbapServiceKeyStore_1.AbapServiceKeyStore; } });
|
|
10
24
|
// ABAP stores (with sapUrl)
|
|
11
25
|
var AbapSessionStore_1 = require("./stores/abap/AbapSessionStore");
|
|
12
26
|
Object.defineProperty(exports, "AbapSessionStore", { enumerable: true, get: function () { return AbapSessionStore_1.AbapSessionStore; } });
|
|
13
27
|
var SafeAbapSessionStore_1 = require("./stores/abap/SafeAbapSessionStore");
|
|
14
28
|
Object.defineProperty(exports, "SafeAbapSessionStore", { enumerable: true, get: function () { return SafeAbapSessionStore_1.SafeAbapSessionStore; } });
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var XsuaaSessionStore_1 = require("./stores/xsuaa/XsuaaSessionStore");
|
|
19
|
-
Object.defineProperty(exports, "XsuaaSessionStore", { enumerable: true, get: function () { return XsuaaSessionStore_1.XsuaaSessionStore; } });
|
|
29
|
+
// Env file stores (for --env=path scenarios)
|
|
30
|
+
var EnvFileSessionStore_1 = require("./stores/env/EnvFileSessionStore");
|
|
31
|
+
Object.defineProperty(exports, "EnvFileSessionStore", { enumerable: true, get: function () { return EnvFileSessionStore_1.EnvFileSessionStore; } });
|
|
20
32
|
var SafeXsuaaSessionStore_1 = require("./stores/xsuaa/SafeXsuaaSessionStore");
|
|
21
33
|
Object.defineProperty(exports, "SafeXsuaaSessionStore", { enumerable: true, get: function () { return SafeXsuaaSessionStore_1.SafeXsuaaSessionStore; } });
|
|
34
|
+
Object.defineProperty(exports, "SafeBtpSessionStore", { enumerable: true, get: function () { return SafeXsuaaSessionStore_1.SafeXsuaaSessionStore; } });
|
|
22
35
|
var XsuaaServiceKeyStore_1 = require("./stores/xsuaa/XsuaaServiceKeyStore");
|
|
23
36
|
Object.defineProperty(exports, "XsuaaServiceKeyStore", { enumerable: true, get: function () { return XsuaaServiceKeyStore_1.XsuaaServiceKeyStore; } });
|
|
37
|
+
Object.defineProperty(exports, "BtpServiceKeyStore", { enumerable: true, get: function () { return XsuaaServiceKeyStore_1.XsuaaServiceKeyStore; } });
|
|
38
|
+
// XSUAA stores
|
|
24
39
|
// BTP stores - aliases for XSUAA (backward compatibility)
|
|
25
|
-
var
|
|
26
|
-
Object.defineProperty(exports, "
|
|
27
|
-
|
|
28
|
-
Object.defineProperty(exports, "SafeBtpSessionStore", { enumerable: true, get: function () { return SafeXsuaaSessionStore_2.SafeXsuaaSessionStore; } });
|
|
29
|
-
var XsuaaServiceKeyStore_2 = require("./stores/xsuaa/XsuaaServiceKeyStore");
|
|
30
|
-
Object.defineProperty(exports, "BtpServiceKeyStore", { enumerable: true, get: function () { return XsuaaServiceKeyStore_2.XsuaaServiceKeyStore; } });
|
|
31
|
-
// Env file stores (for --env=path scenarios)
|
|
32
|
-
var EnvFileSessionStore_1 = require("./stores/env/EnvFileSessionStore");
|
|
33
|
-
Object.defineProperty(exports, "EnvFileSessionStore", { enumerable: true, get: function () { return EnvFileSessionStore_1.EnvFileSessionStore; } });
|
|
34
|
-
// Error classes
|
|
35
|
-
var StoreErrors_1 = require("./errors/StoreErrors");
|
|
36
|
-
Object.defineProperty(exports, "StoreError", { enumerable: true, get: function () { return StoreErrors_1.StoreError; } });
|
|
37
|
-
Object.defineProperty(exports, "FileNotFoundError", { enumerable: true, get: function () { return StoreErrors_1.FileNotFoundError; } });
|
|
38
|
-
Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return StoreErrors_1.ParseError; } });
|
|
39
|
-
Object.defineProperty(exports, "InvalidConfigError", { enumerable: true, get: function () { return StoreErrors_1.InvalidConfigError; } });
|
|
40
|
-
Object.defineProperty(exports, "StorageError", { enumerable: true, get: function () { return StoreErrors_1.StorageError; } });
|
|
41
|
-
// Utils
|
|
42
|
-
var pathResolver_1 = require("./utils/pathResolver");
|
|
43
|
-
Object.defineProperty(exports, "resolveSearchPaths", { enumerable: true, get: function () { return pathResolver_1.resolveSearchPaths; } });
|
|
44
|
-
Object.defineProperty(exports, "findFileInPaths", { enumerable: true, get: function () { return pathResolver_1.findFileInPaths; } });
|
|
45
|
-
var JsonFileHandler_1 = require("./utils/JsonFileHandler");
|
|
46
|
-
Object.defineProperty(exports, "JsonFileHandler", { enumerable: true, get: function () { return JsonFileHandler_1.JsonFileHandler; } });
|
|
47
|
-
var EnvFileHandler_1 = require("./utils/EnvFileHandler");
|
|
48
|
-
Object.defineProperty(exports, "EnvFileHandler", { enumerable: true, get: function () { return EnvFileHandler_1.EnvFileHandler; } });
|
|
40
|
+
var XsuaaSessionStore_1 = require("./stores/xsuaa/XsuaaSessionStore");
|
|
41
|
+
Object.defineProperty(exports, "XsuaaSessionStore", { enumerable: true, get: function () { return XsuaaSessionStore_1.XsuaaSessionStore; } });
|
|
42
|
+
Object.defineProperty(exports, "BtpSessionStore", { enumerable: true, get: function () { return XsuaaSessionStore_1.XsuaaSessionStore; } });
|
|
49
43
|
var constants_1 = require("./utils/constants");
|
|
50
44
|
Object.defineProperty(exports, "ABAP_AUTHORIZATION_VARS", { enumerable: true, get: function () { return constants_1.ABAP_AUTHORIZATION_VARS; } });
|
|
51
45
|
Object.defineProperty(exports, "ABAP_CONNECTION_VARS", { enumerable: true, get: function () { return constants_1.ABAP_CONNECTION_VARS; } });
|
|
@@ -53,8 +47,11 @@ Object.defineProperty(exports, "BTP_AUTHORIZATION_VARS", { enumerable: true, get
|
|
|
53
47
|
Object.defineProperty(exports, "BTP_CONNECTION_VARS", { enumerable: true, get: function () { return constants_1.BTP_CONNECTION_VARS; } });
|
|
54
48
|
Object.defineProperty(exports, "XSUAA_AUTHORIZATION_VARS", { enumerable: true, get: function () { return constants_1.XSUAA_AUTHORIZATION_VARS; } });
|
|
55
49
|
Object.defineProperty(exports, "XSUAA_CONNECTION_VARS", { enumerable: true, get: function () { return constants_1.XSUAA_CONNECTION_VARS; } });
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
var EnvFileHandler_1 = require("./utils/EnvFileHandler");
|
|
51
|
+
Object.defineProperty(exports, "EnvFileHandler", { enumerable: true, get: function () { return EnvFileHandler_1.EnvFileHandler; } });
|
|
52
|
+
var JsonFileHandler_1 = require("./utils/JsonFileHandler");
|
|
53
|
+
Object.defineProperty(exports, "JsonFileHandler", { enumerable: true, get: function () { return JsonFileHandler_1.JsonFileHandler; } });
|
|
54
|
+
// Utils
|
|
55
|
+
var pathResolver_1 = require("./utils/pathResolver");
|
|
56
|
+
Object.defineProperty(exports, "findFileInPaths", { enumerable: true, get: function () { return pathResolver_1.findFileInPaths; } });
|
|
57
|
+
Object.defineProperty(exports, "resolveSearchPaths", { enumerable: true, get: function () { return pathResolver_1.resolveSearchPaths; } });
|
|
@@ -41,8 +41,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
})();
|
|
42
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
43
|
exports.loadServiceKey = loadServiceKey;
|
|
44
|
-
const fs = __importStar(require("fs"));
|
|
45
|
-
const path = __importStar(require("path"));
|
|
44
|
+
const fs = __importStar(require("node:fs"));
|
|
45
|
+
const path = __importStar(require("node:path"));
|
|
46
46
|
const AbapServiceKeyParser_1 = require("../../parsers/abap/AbapServiceKeyParser");
|
|
47
47
|
const XsuaaServiceKeyParser_1 = require("../../parsers/xsuaa/XsuaaServiceKeyParser");
|
|
48
48
|
/**
|
|
@@ -62,10 +62,7 @@ async function loadServiceKey(destination, directory) {
|
|
|
62
62
|
const fileContent = fs.readFileSync(serviceKeyPath, 'utf8');
|
|
63
63
|
const rawData = JSON.parse(fileContent);
|
|
64
64
|
// Try parsers in order: ABAP format first, then XSUAA format
|
|
65
|
-
const parsers = [
|
|
66
|
-
new AbapServiceKeyParser_1.AbapServiceKeyParser(),
|
|
67
|
-
new XsuaaServiceKeyParser_1.XsuaaServiceKeyParser(),
|
|
68
|
-
];
|
|
65
|
+
const parsers = [new AbapServiceKeyParser_1.AbapServiceKeyParser(), new XsuaaServiceKeyParser_1.XsuaaServiceKeyParser()];
|
|
69
66
|
for (const parser of parsers) {
|
|
70
67
|
if (parser.canParse(rawData)) {
|
|
71
68
|
return parser.parse(rawData);
|
|
@@ -45,8 +45,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
45
45
|
})();
|
|
46
46
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
47
|
exports.loadXSUAAServiceKey = loadXSUAAServiceKey;
|
|
48
|
-
const fs = __importStar(require("fs"));
|
|
49
|
-
const path = __importStar(require("path"));
|
|
48
|
+
const fs = __importStar(require("node:fs"));
|
|
49
|
+
const path = __importStar(require("node:path"));
|
|
50
50
|
const XsuaaServiceKeyParser_1 = require("../../parsers/xsuaa/XsuaaServiceKeyParser");
|
|
51
51
|
/**
|
|
52
52
|
* Load XSUAA service key from {destination}.json file
|
|
@@ -31,12 +31,12 @@ export declare class AbapServiceKeyParser {
|
|
|
31
31
|
* @param rawData Raw JSON data from service key file
|
|
32
32
|
* @returns true if data has nested uaa object, false otherwise
|
|
33
33
|
*/
|
|
34
|
-
canParse(rawData:
|
|
34
|
+
canParse(rawData: unknown): boolean;
|
|
35
35
|
/**
|
|
36
36
|
* Parse raw service key data
|
|
37
37
|
* @param rawData Raw JSON data from service key file
|
|
38
38
|
* @returns Parsed service key object
|
|
39
39
|
* @throws Error if data cannot be parsed or is invalid
|
|
40
40
|
*/
|
|
41
|
-
parse(rawData:
|
|
41
|
+
parse(rawData: unknown): unknown;
|
|
42
42
|
}
|
|
@@ -36,8 +36,14 @@ class AbapServiceKeyParser {
|
|
|
36
36
|
* @returns true if data has nested uaa object, false otherwise
|
|
37
37
|
*/
|
|
38
38
|
canParse(rawData) {
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
if (!rawData || typeof rawData !== 'object' || Array.isArray(rawData)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const data = rawData;
|
|
43
|
+
const result = !!(data.uaa &&
|
|
44
|
+
typeof data.uaa === 'object' &&
|
|
45
|
+
!Array.isArray(data.uaa));
|
|
46
|
+
this.log?.debug(`canParse check: hasUaa(${!!data.uaa}), result(${result})`);
|
|
41
47
|
return result;
|
|
42
48
|
}
|
|
43
49
|
/**
|
|
@@ -47,21 +53,28 @@ class AbapServiceKeyParser {
|
|
|
47
53
|
* @throws Error if data cannot be parsed or is invalid
|
|
48
54
|
*/
|
|
49
55
|
parse(rawData) {
|
|
50
|
-
|
|
56
|
+
if (!rawData || typeof rawData !== 'object' || Array.isArray(rawData)) {
|
|
57
|
+
throw new Error('Service key data must be an object');
|
|
58
|
+
}
|
|
59
|
+
const data = rawData;
|
|
60
|
+
this.log?.debug(`Parsing ABAP service key: hasUaa(${!!data.uaa}), keys(${Object.keys(data).join(', ')})`);
|
|
51
61
|
if (!this.canParse(rawData)) {
|
|
52
62
|
this.log?.error(`Service key does not match ABAP format: missing uaa object`);
|
|
53
63
|
throw new Error('Service key does not match ABAP format (missing uaa object)');
|
|
54
64
|
}
|
|
65
|
+
// After canParse, we know uaa exists and is an object
|
|
66
|
+
const uaa = data.uaa;
|
|
55
67
|
// Validate UAA configuration
|
|
56
|
-
const hasUrl =
|
|
57
|
-
const hasClientId =
|
|
58
|
-
const hasClientSecret =
|
|
68
|
+
const hasUrl = typeof uaa.url === 'string' && uaa.url.length > 0;
|
|
69
|
+
const hasClientId = typeof uaa.clientid === 'string' && uaa.clientid.length > 0;
|
|
70
|
+
const hasClientSecret = typeof uaa.clientsecret === 'string' && uaa.clientsecret.length > 0;
|
|
59
71
|
this.log?.debug(`UAA validation: url(${hasUrl}), clientid(${hasClientId}), clientsecret(${hasClientSecret})`);
|
|
60
72
|
if (!hasUrl || !hasClientId || !hasClientSecret) {
|
|
61
73
|
this.log?.error(`Service key uaa object missing required fields: url(${hasUrl}), clientid(${hasClientId}), clientsecret(${hasClientSecret})`);
|
|
62
74
|
throw new Error('Service key "uaa" object missing required fields: url, clientid, clientsecret');
|
|
63
75
|
}
|
|
64
|
-
|
|
76
|
+
const uaaUrl = typeof uaa.url === 'string' ? uaa.url : '';
|
|
77
|
+
this.log?.debug(`ABAP service key parsed successfully: uaaUrl(${uaaUrl.substring(0, 40)}...), hasAbap(${!!data.abap})`);
|
|
65
78
|
return rawData;
|
|
66
79
|
}
|
|
67
80
|
}
|
|
@@ -26,12 +26,12 @@ export declare class XsuaaServiceKeyParser {
|
|
|
26
26
|
* @param rawData Raw JSON data from service key file
|
|
27
27
|
* @returns true if data has direct XSUAA fields (url, clientid, clientsecret) without nested uaa object
|
|
28
28
|
*/
|
|
29
|
-
canParse(rawData:
|
|
29
|
+
canParse(rawData: unknown): boolean;
|
|
30
30
|
/**
|
|
31
31
|
* Parse raw service key data
|
|
32
32
|
* @param rawData Raw JSON data from service key file
|
|
33
33
|
* @returns Parsed service key object (normalized format)
|
|
34
34
|
* @throws Error if data cannot be parsed or is invalid
|
|
35
35
|
*/
|
|
36
|
-
parse(rawData:
|
|
36
|
+
parse(rawData: unknown): unknown;
|
|
37
37
|
}
|
|
@@ -35,15 +35,16 @@ class XsuaaServiceKeyParser {
|
|
|
35
35
|
this.log?.debug(`canParse check: invalid type, result(false)`);
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
|
+
const data = rawData;
|
|
38
39
|
// Check for nested uaa object (ABAP format) - should not have it
|
|
39
|
-
if (
|
|
40
|
+
if (data.uaa) {
|
|
40
41
|
this.log?.debug(`canParse check: has nested uaa (ABAP format), result(false)`);
|
|
41
42
|
return false;
|
|
42
43
|
}
|
|
43
44
|
// Check for required XSUAA fields at root level
|
|
44
|
-
const hasUrl = typeof
|
|
45
|
-
const hasClientId = typeof
|
|
46
|
-
const hasClientSecret = typeof
|
|
45
|
+
const hasUrl = typeof data.url === 'string' && data.url.length > 0;
|
|
46
|
+
const hasClientId = typeof data.clientid === 'string' && data.clientid.length > 0;
|
|
47
|
+
const hasClientSecret = typeof data.clientsecret === 'string' && data.clientsecret.length > 0;
|
|
47
48
|
const result = hasUrl && hasClientId && hasClientSecret;
|
|
48
49
|
this.log?.debug(`canParse check: url(${hasUrl}), clientid(${hasClientId}), clientsecret(${hasClientSecret}), result(${result})`);
|
|
49
50
|
return result;
|
|
@@ -55,32 +56,39 @@ class XsuaaServiceKeyParser {
|
|
|
55
56
|
* @throws Error if data cannot be parsed or is invalid
|
|
56
57
|
*/
|
|
57
58
|
parse(rawData) {
|
|
58
|
-
|
|
59
|
+
if (!rawData || typeof rawData !== 'object' || Array.isArray(rawData)) {
|
|
60
|
+
throw new Error('Service key data must be an object');
|
|
61
|
+
}
|
|
62
|
+
const data = rawData;
|
|
63
|
+
this.log?.debug(`Parsing XSUAA service key: hasUrl(${!!data.url}), hasClientId(${!!data.clientid}), hasClientSecret(${!!data.clientsecret}), keys(${Object.keys(data).join(', ')})`);
|
|
59
64
|
if (!this.canParse(rawData)) {
|
|
60
65
|
this.log?.error(`Service key does not match XSUAA format: missing required fields at root level`);
|
|
61
66
|
throw new Error('Service key does not match XSUAA format (missing url, clientid, or clientsecret at root level)');
|
|
62
67
|
}
|
|
68
|
+
// After canParse, we know url, clientid, and clientsecret exist and are strings
|
|
69
|
+
const uaaUrl = typeof data.url === 'string' ? data.url : '';
|
|
70
|
+
const clientId = typeof data.clientid === 'string' ? data.clientid : '';
|
|
71
|
+
const clientSecret = typeof data.clientsecret === 'string' ? data.clientsecret : '';
|
|
63
72
|
// Normalize to standard format
|
|
64
73
|
// For authorization (OAuth2 authorize endpoint), use 'url' (not 'apiurl')
|
|
65
74
|
// 'apiurl' is for token endpoint, but authorization uses base 'url'
|
|
66
|
-
const uaaUrl = rawData.url;
|
|
67
75
|
const result = {
|
|
68
76
|
uaa: {
|
|
69
77
|
url: uaaUrl,
|
|
70
|
-
clientid:
|
|
71
|
-
clientsecret:
|
|
78
|
+
clientid: clientId,
|
|
79
|
+
clientsecret: clientSecret,
|
|
72
80
|
},
|
|
73
81
|
// Preserve abap.url if present
|
|
74
|
-
abap:
|
|
82
|
+
abap: data.abap,
|
|
75
83
|
// Preserve other optional fields
|
|
76
|
-
url:
|
|
77
|
-
apiurl:
|
|
78
|
-
sap_url:
|
|
79
|
-
client:
|
|
80
|
-
sap_client:
|
|
81
|
-
language:
|
|
84
|
+
url: data.url, // UAA URL
|
|
85
|
+
apiurl: data.apiurl, // API URL (prioritized for UAA)
|
|
86
|
+
sap_url: data.sap_url,
|
|
87
|
+
client: data.client,
|
|
88
|
+
sap_client: data.sap_client,
|
|
89
|
+
language: data.language,
|
|
82
90
|
};
|
|
83
|
-
this.log?.debug(`XSUAA service key parsed successfully: uaaUrl(${uaaUrl.substring(0, 40)}...), hasAbap(${!!
|
|
91
|
+
this.log?.debug(`XSUAA service key parsed successfully: uaaUrl(${uaaUrl.substring(0, 40)}...), hasAbap(${!!data.abap})`);
|
|
84
92
|
return result;
|
|
85
93
|
}
|
|
86
94
|
}
|
|
@@ -37,8 +37,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.loadEnvFile = loadEnvFile;
|
|
40
|
-
const fs = __importStar(require("fs"));
|
|
41
|
-
const path = __importStar(require("path"));
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
42
|
const dotenv = __importStar(require("dotenv"));
|
|
43
43
|
const constants_1 = require("../../utils/constants");
|
|
44
44
|
/**
|
|
@@ -78,7 +78,7 @@ async function loadEnvFile(destination, directory, log) {
|
|
|
78
78
|
// If neither is present, it's OK - auth can be set later (e.g., via setAuthorizationConfig)
|
|
79
79
|
const isBasicAuth = !!(username && password) && (!jwtToken || jwtToken.trim() === '');
|
|
80
80
|
const isJwtAuth = !!(jwtToken && jwtToken.trim() !== '');
|
|
81
|
-
const
|
|
81
|
+
const _hasNoAuth = !isBasicAuth && !isJwtAuth;
|
|
82
82
|
const config = {
|
|
83
83
|
sapUrl: sapUrl.trim(),
|
|
84
84
|
};
|
|
@@ -102,7 +102,8 @@ async function loadEnvFile(destination, directory, log) {
|
|
|
102
102
|
config.sapClient = parsed[constants_1.ABAP_CONNECTION_VARS.SAP_CLIENT].trim();
|
|
103
103
|
}
|
|
104
104
|
if (parsed[constants_1.ABAP_AUTHORIZATION_VARS.REFRESH_TOKEN]) {
|
|
105
|
-
config.refreshToken =
|
|
105
|
+
config.refreshToken =
|
|
106
|
+
parsed[constants_1.ABAP_AUTHORIZATION_VARS.REFRESH_TOKEN].trim();
|
|
106
107
|
}
|
|
107
108
|
if (parsed[constants_1.ABAP_AUTHORIZATION_VARS.UAA_URL]) {
|
|
108
109
|
config.uaaUrl = parsed[constants_1.ABAP_AUTHORIZATION_VARS.UAA_URL].trim();
|
|
@@ -111,7 +112,8 @@ async function loadEnvFile(destination, directory, log) {
|
|
|
111
112
|
config.uaaClientId = parsed[constants_1.ABAP_AUTHORIZATION_VARS.UAA_CLIENT_ID].trim();
|
|
112
113
|
}
|
|
113
114
|
if (parsed[constants_1.ABAP_AUTHORIZATION_VARS.UAA_CLIENT_SECRET]) {
|
|
114
|
-
config.uaaClientSecret =
|
|
115
|
+
config.uaaClientSecret =
|
|
116
|
+
parsed[constants_1.ABAP_AUTHORIZATION_VARS.UAA_CLIENT_SECRET].trim();
|
|
115
117
|
}
|
|
116
118
|
if (parsed[constants_1.ABAP_CONNECTION_VARS.SAP_LANGUAGE]) {
|
|
117
119
|
config.language = parsed[constants_1.ABAP_CONNECTION_VARS.SAP_LANGUAGE].trim();
|
|
@@ -37,8 +37,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.saveTokenToEnv = saveTokenToEnv;
|
|
40
|
-
const fs = __importStar(require("fs"));
|
|
41
|
-
const path = __importStar(require("path"));
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
42
|
const constants_1 = require("../../utils/constants");
|
|
43
43
|
/**
|
|
44
44
|
* Save token to {destination}.env file
|
|
@@ -131,7 +131,7 @@ async function saveTokenToEnv(destination, savePath, config, log) {
|
|
|
131
131
|
: value;
|
|
132
132
|
envLines.push(`${key}=${escapedValue}`);
|
|
133
133
|
}
|
|
134
|
-
const envContent = envLines.join('\n')
|
|
134
|
+
const envContent = `${envLines.join('\n')}\n`;
|
|
135
135
|
log?.debug(`Writing ${envLines.length} variables to env file: ${Object.keys(config).join(', ')}`);
|
|
136
136
|
// Write to temp file
|
|
137
137
|
fs.writeFileSync(tempFilePath, envContent, 'utf8');
|
|
@@ -140,5 +140,5 @@ async function saveTokenToEnv(destination, savePath, config, log) {
|
|
|
140
140
|
const authInfo = hasBasicAuth
|
|
141
141
|
? `basic auth (username: ${config.username})`
|
|
142
142
|
: `JWT token(${tokenLength} chars)`;
|
|
143
|
-
log?.info(`Token saved to ${envFilePath}: ${authInfo}, sapUrl(${config.sapUrl ? config.sapUrl.substring(0, 50)
|
|
143
|
+
log?.info(`Token saved to ${envFilePath}: ${authInfo}, sapUrl(${config.sapUrl ? `${config.sapUrl.substring(0, 50)}...` : 'none'}), variables(${envLines.length})`);
|
|
144
144
|
}
|
|
@@ -37,8 +37,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.loadXsuaaEnvFile = loadXsuaaEnvFile;
|
|
40
|
-
const fs = __importStar(require("fs"));
|
|
41
|
-
const path = __importStar(require("path"));
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
42
|
const dotenv = __importStar(require("dotenv"));
|
|
43
43
|
const constants_1 = require("../../utils/constants");
|
|
44
44
|
/**
|
|
@@ -62,7 +62,9 @@ async function loadXsuaaEnvFile(destination, directory, log) {
|
|
|
62
62
|
const envContent = fs.readFileSync(envFilePath, 'utf8');
|
|
63
63
|
log?.debug(`XSUAA env file read successfully, size: ${envContent.length} bytes`);
|
|
64
64
|
const parsed = dotenv.parse(envContent);
|
|
65
|
-
log?.debug(`Parsed XSUAA env variables: ${Object.keys(parsed)
|
|
65
|
+
log?.debug(`Parsed XSUAA env variables: ${Object.keys(parsed)
|
|
66
|
+
.filter((k) => k.startsWith('XSUAA_'))
|
|
67
|
+
.join(', ')}`);
|
|
66
68
|
// Extract required fields (XSUAA_* variables)
|
|
67
69
|
const jwtToken = parsed[constants_1.XSUAA_CONNECTION_VARS.AUTHORIZATION_TOKEN];
|
|
68
70
|
log?.debug(`Extracted fields: hasJwtToken(${jwtToken !== undefined && jwtToken !== null})`);
|
|
@@ -77,22 +79,25 @@ async function loadXsuaaEnvFile(destination, directory, log) {
|
|
|
77
79
|
};
|
|
78
80
|
// mcpUrl can be loaded from .env file as additional variable (not part of CONNECTION_VARS, but can be stored)
|
|
79
81
|
// URL comes from elsewhere (YAML config, parameter, or request header), but can be stored in .env
|
|
80
|
-
if (parsed
|
|
81
|
-
config.mcpUrl = parsed
|
|
82
|
+
if (parsed.XSUAA_MCP_URL) {
|
|
83
|
+
config.mcpUrl = parsed.XSUAA_MCP_URL.trim();
|
|
82
84
|
}
|
|
83
85
|
if (parsed[constants_1.XSUAA_AUTHORIZATION_VARS.REFRESH_TOKEN]) {
|
|
84
|
-
config.refreshToken =
|
|
86
|
+
config.refreshToken =
|
|
87
|
+
parsed[constants_1.XSUAA_AUTHORIZATION_VARS.REFRESH_TOKEN].trim();
|
|
85
88
|
}
|
|
86
89
|
if (parsed[constants_1.XSUAA_AUTHORIZATION_VARS.UAA_URL]) {
|
|
87
90
|
config.uaaUrl = parsed[constants_1.XSUAA_AUTHORIZATION_VARS.UAA_URL].trim();
|
|
88
91
|
}
|
|
89
92
|
if (parsed[constants_1.XSUAA_AUTHORIZATION_VARS.UAA_CLIENT_ID]) {
|
|
90
|
-
config.uaaClientId =
|
|
93
|
+
config.uaaClientId =
|
|
94
|
+
parsed[constants_1.XSUAA_AUTHORIZATION_VARS.UAA_CLIENT_ID].trim();
|
|
91
95
|
}
|
|
92
96
|
if (parsed[constants_1.XSUAA_AUTHORIZATION_VARS.UAA_CLIENT_SECRET]) {
|
|
93
|
-
config.uaaClientSecret =
|
|
97
|
+
config.uaaClientSecret =
|
|
98
|
+
parsed[constants_1.XSUAA_AUTHORIZATION_VARS.UAA_CLIENT_SECRET].trim();
|
|
94
99
|
}
|
|
95
|
-
log?.info(`XSUAA env config loaded from ${envFilePath}: token(${config.jwtToken.length} chars), hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl}), mcpUrl(${config.mcpUrl ? config.mcpUrl.substring(0, 50)
|
|
100
|
+
log?.info(`XSUAA env config loaded from ${envFilePath}: token(${config.jwtToken.length} chars), hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl}), mcpUrl(${config.mcpUrl ? `${config.mcpUrl.substring(0, 50)}...` : 'none'})`);
|
|
96
101
|
return config;
|
|
97
102
|
}
|
|
98
103
|
catch (error) {
|
|
@@ -37,8 +37,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.saveXsuaaTokenToEnv = saveXsuaaTokenToEnv;
|
|
40
|
-
const fs = __importStar(require("fs"));
|
|
41
|
-
const path = __importStar(require("path"));
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
42
|
const constants_1 = require("../../utils/constants");
|
|
43
43
|
/**
|
|
44
44
|
* Save XSUAA token to {destination}.env file using XSUAA_* variables
|
|
@@ -51,7 +51,7 @@ async function saveXsuaaTokenToEnv(destination, savePath, config, log) {
|
|
|
51
51
|
const envFilePath = path.join(savePath, `${destination}.env`);
|
|
52
52
|
const tempFilePath = `${envFilePath}.tmp`;
|
|
53
53
|
log?.debug(`Saving XSUAA token to env file: ${envFilePath}`);
|
|
54
|
-
log?.debug(`Config to save: token(${config.jwtToken.length} chars), hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl}), mcpUrl(${config.mcpUrl ? config.mcpUrl.substring(0, 50)
|
|
54
|
+
log?.debug(`Config to save: token(${config.jwtToken.length} chars), hasRefreshToken(${!!config.refreshToken}), hasUaaUrl(${!!config.uaaUrl}), mcpUrl(${config.mcpUrl ? `${config.mcpUrl.substring(0, 50)}...` : 'none'})`);
|
|
55
55
|
// Ensure directory exists
|
|
56
56
|
if (!fs.existsSync(savePath)) {
|
|
57
57
|
log?.debug(`Creating directory: ${savePath}`);
|
|
@@ -79,8 +79,13 @@ async function saveXsuaaTokenToEnv(destination, savePath, config, log) {
|
|
|
79
79
|
if (match) {
|
|
80
80
|
const key = match[1].trim();
|
|
81
81
|
// Skip old SAP_* variables for XSUAA (we use XSUAA_* now)
|
|
82
|
-
if (key.startsWith('SAP_') &&
|
|
83
|
-
key === '
|
|
82
|
+
if (key.startsWith('SAP_') &&
|
|
83
|
+
(key === 'SAP_URL' ||
|
|
84
|
+
key === 'SAP_JWT_TOKEN' ||
|
|
85
|
+
key === 'SAP_REFRESH_TOKEN' ||
|
|
86
|
+
key === 'SAP_UAA_URL' ||
|
|
87
|
+
key === 'SAP_UAA_CLIENT_ID' ||
|
|
88
|
+
key === 'SAP_UAA_CLIENT_SECRET')) {
|
|
84
89
|
continue; // Don't preserve old SAP_* variables
|
|
85
90
|
}
|
|
86
91
|
const value = match[2].trim().replace(/^["']|["']$/g, ''); // Remove quotes
|
|
@@ -116,11 +121,11 @@ async function saveXsuaaTokenToEnv(destination, savePath, config, log) {
|
|
|
116
121
|
: value;
|
|
117
122
|
envLines.push(`${key}=${escapedValue}`);
|
|
118
123
|
}
|
|
119
|
-
const envContent = envLines.join('\n')
|
|
124
|
+
const envContent = `${envLines.join('\n')}\n`;
|
|
120
125
|
log?.debug(`Writing ${envLines.length} XSUAA variables to env file: ${Object.keys(config).join(', ')}`);
|
|
121
126
|
// Write to temp file
|
|
122
127
|
fs.writeFileSync(tempFilePath, envContent, 'utf8');
|
|
123
128
|
// Atomic rename
|
|
124
129
|
fs.renameSync(tempFilePath, envFilePath);
|
|
125
|
-
log?.info(`XSUAA token saved to ${envFilePath}: token(${config.jwtToken.length} chars), mcpUrl(${config.mcpUrl ? config.mcpUrl.substring(0, 50)
|
|
130
|
+
log?.info(`XSUAA token saved to ${envFilePath}: token(${config.jwtToken.length} chars), mcpUrl(${config.mcpUrl ? `${config.mcpUrl.substring(0, 50)}...` : 'none'}), variables(${envLines.length})`);
|
|
126
131
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ABAP Service key store - reads ABAP service keys from {destination}.json files
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
4
|
+
import type { IAuthorizationConfig, IConfig, IConnectionConfig, ILogger, IServiceKeyStore } from '@mcp-abap-adt/interfaces';
|
|
5
5
|
/**
|
|
6
6
|
* ABAP Service key store implementation
|
|
7
7
|
*
|
|
@@ -37,10 +37,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.AbapServiceKeyStore = void 0;
|
|
40
|
-
const
|
|
41
|
-
const AbapServiceKeyParser_1 = require("../../parsers/abap/AbapServiceKeyParser");
|
|
40
|
+
const path = __importStar(require("node:path"));
|
|
42
41
|
const StoreErrors_1 = require("../../errors/StoreErrors");
|
|
43
|
-
const
|
|
42
|
+
const AbapServiceKeyParser_1 = require("../../parsers/abap/AbapServiceKeyParser");
|
|
43
|
+
const JsonFileHandler_1 = require("../../utils/JsonFileHandler");
|
|
44
44
|
/**
|
|
45
45
|
* ABAP Service key store implementation
|
|
46
46
|
*
|
|
@@ -99,7 +99,10 @@ class AbapServiceKeyStore {
|
|
|
99
99
|
}
|
|
100
100
|
const key = parsed;
|
|
101
101
|
this.log?.debug(`Parsed service key structure: hasUaa(${!!key.uaa}), uaaKeys(${key.uaa ? Object.keys(key.uaa).join(', ') : 'none'})`);
|
|
102
|
-
if (!key.uaa ||
|
|
102
|
+
if (!key.uaa ||
|
|
103
|
+
!key.uaa.url ||
|
|
104
|
+
!key.uaa.clientid ||
|
|
105
|
+
!key.uaa.clientsecret) {
|
|
103
106
|
this.log?.warn(`Service key for ${destination} missing required UAA fields: url(${!!key.uaa?.url}), clientid(${!!key.uaa?.clientid}), clientsecret(${!!key.uaa?.clientsecret})`);
|
|
104
107
|
return null;
|
|
105
108
|
}
|
|
@@ -140,7 +143,9 @@ class AbapServiceKeyStore {
|
|
|
140
143
|
const key = parsed;
|
|
141
144
|
this.log?.debug(`Parsed service key structure: hasAbap(${!!key.abap}), hasSapUrl(${!!key.sap_url}), hasUrl(${!!key.url})`);
|
|
142
145
|
// Service key doesn't have tokens - only URLs and client info
|
|
143
|
-
const serviceUrl = key.abap?.url ||
|
|
146
|
+
const serviceUrl = key.abap?.url ||
|
|
147
|
+
key.sap_url ||
|
|
148
|
+
(key.url && !key.url.includes('authentication') ? key.url : undefined);
|
|
144
149
|
const sapClient = key.abap?.client || key.sap_client || key.client;
|
|
145
150
|
const language = key.abap?.language || key.language;
|
|
146
151
|
const result = {
|
|
@@ -149,7 +154,7 @@ class AbapServiceKeyStore {
|
|
|
149
154
|
sapClient,
|
|
150
155
|
language,
|
|
151
156
|
};
|
|
152
|
-
this.log?.info(`Connection config loaded from ${filePath}: serviceUrl(${serviceUrl ? serviceUrl.substring(0, 50)
|
|
157
|
+
this.log?.info(`Connection config loaded from ${filePath}: serviceUrl(${serviceUrl ? `${serviceUrl.substring(0, 50)}...` : 'none'}), client(${sapClient || 'none'}), language(${language || 'none'})`);
|
|
153
158
|
return result;
|
|
154
159
|
}
|
|
155
160
|
catch (error) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Stores full ABAP configuration: SAP URL (sapUrl), JWT token, refresh token, UAA config, SAP client, language.
|
|
6
6
|
* This extends base BTP store by adding sapUrl requirement.
|
|
7
7
|
*/
|
|
8
|
-
import type { IAuthorizationConfig,
|
|
8
|
+
import type { IAuthorizationConfig, IConfig, IConnectionConfig, ILogger, ISessionStore } from '@mcp-abap-adt/interfaces';
|
|
9
9
|
/**
|
|
10
10
|
* ABAP Session store implementation
|
|
11
11
|
*
|