@mcp-abap-adt/auth-broker 0.1.1 → 0.1.2
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 +20 -0
- package/dist/AuthBroker.d.ts +28 -21
- package/dist/AuthBroker.d.ts.map +1 -1
- package/dist/AuthBroker.js +146 -170
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/stores/FileServiceKeyStore.d.ts +38 -0
- package/dist/stores/FileServiceKeyStore.d.ts.map +1 -0
- package/dist/stores/FileServiceKeyStore.js +47 -0
- package/dist/stores/FileSessionStore.d.ts +50 -0
- package/dist/stores/FileSessionStore.d.ts.map +1 -0
- package/dist/stores/FileSessionStore.js +116 -0
- package/dist/stores/index.d.ts +7 -0
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/index.js +10 -0
- package/dist/stores/interfaces.d.ts +47 -0
- package/dist/stores/interfaces.d.ts.map +1 -0
- package/dist/stores/interfaces.js +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the complete list.
|
|
11
11
|
|
|
12
|
+
## [0.1.2] - 2025-11-30
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- **Storage Interfaces** - New interfaces for custom storage implementations
|
|
16
|
+
- `ServiceKeyStore` interface - for reading service keys
|
|
17
|
+
- `SessionStore` interface - for reading/writing session data (tokens, configuration)
|
|
18
|
+
- `FileServiceKeyStore` - default file-based implementation for service keys
|
|
19
|
+
- `FileSessionStore` - default file-based implementation for sessions
|
|
20
|
+
- **Dependency Injection Support** - AuthBroker now accepts custom stores via constructor
|
|
21
|
+
- Can provide custom `ServiceKeyStore` and `SessionStore` implementations
|
|
22
|
+
- Default to file-based stores if not provided (backward compatible)
|
|
23
|
+
- Enables custom storage backends (database, cloud, etc.) without creating new packages
|
|
24
|
+
- New API: constructor accepts object with `serviceKeyStore` and `sessionStore` properties
|
|
25
|
+
- Backward compatible: still accepts `searchPaths` as first parameter (string/array)
|
|
26
|
+
|
|
27
|
+
### Technical Details
|
|
28
|
+
- Storage abstraction allows consumers to provide custom implementations
|
|
29
|
+
- No breaking changes - existing code continues to work
|
|
30
|
+
- File-based stores remain the default implementation
|
|
31
|
+
|
|
12
32
|
## [0.1.1] - 2025-11-30
|
|
13
33
|
|
|
14
34
|
### Added
|
package/dist/AuthBroker.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Main AuthBroker class for managing JWT tokens based on destinations
|
|
3
3
|
*/
|
|
4
4
|
import { Logger } from './logger';
|
|
5
|
+
import { ServiceKeyStore, SessionStore } from './stores/interfaces';
|
|
5
6
|
/**
|
|
6
7
|
* AuthBroker manages JWT authentication tokens for destinations
|
|
7
8
|
*/
|
|
@@ -9,26 +10,33 @@ export declare class AuthBroker {
|
|
|
9
10
|
private searchPaths;
|
|
10
11
|
private browser;
|
|
11
12
|
private logger;
|
|
13
|
+
private serviceKeyStore;
|
|
14
|
+
private sessionStore;
|
|
12
15
|
/**
|
|
13
16
|
* Create a new AuthBroker instance
|
|
14
|
-
* @param
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* @param searchPathsOrStores Optional search paths for .env and .json files (backward compatibility),
|
|
18
|
+
* OR object with custom stores.
|
|
19
|
+
* If string/array: creates default file-based stores with these paths.
|
|
20
|
+
* If object: uses provided stores (searchPaths ignored).
|
|
21
|
+
* Priority for searchPaths:
|
|
22
|
+
* 1. Constructor parameter (highest)
|
|
23
|
+
* 2. AUTH_BROKER_PATH environment variable (colon/semicolon-separated)
|
|
24
|
+
* 3. Current working directory (lowest)
|
|
20
25
|
* @param browser Optional browser name for authentication (chrome, edge, firefox, system, none).
|
|
21
26
|
* Default: 'system' (system default browser).
|
|
22
27
|
* Use 'none' to print URL instead of opening browser.
|
|
23
28
|
* @param logger Optional logger instance. If not provided, uses default logger.
|
|
24
29
|
*/
|
|
25
|
-
constructor(
|
|
30
|
+
constructor(searchPathsOrStores?: string | string[] | {
|
|
31
|
+
serviceKeyStore?: ServiceKeyStore;
|
|
32
|
+
sessionStore?: SessionStore;
|
|
33
|
+
}, browser?: string, logger?: Logger);
|
|
26
34
|
/**
|
|
27
35
|
* Get authentication token for destination.
|
|
28
|
-
* Tries to load from
|
|
36
|
+
* Tries to load from session store, validates it, and refreshes if needed.
|
|
29
37
|
* @param destination Destination name (e.g., "TRIAL")
|
|
30
38
|
* @returns Promise that resolves to JWT token string
|
|
31
|
-
* @throws Error if neither
|
|
39
|
+
* @throws Error if neither session data nor service key found
|
|
32
40
|
*/
|
|
33
41
|
getToken(destination: string): Promise<string>;
|
|
34
42
|
/**
|
|
@@ -38,24 +46,18 @@ export declare class AuthBroker {
|
|
|
38
46
|
* @returns Promise that resolves to new JWT token string
|
|
39
47
|
*/
|
|
40
48
|
refreshToken(destination: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Internal refresh token implementation
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
private refreshTokenInternal;
|
|
41
54
|
/**
|
|
42
55
|
* Get SAP URL for destination.
|
|
43
|
-
* Tries to load from
|
|
56
|
+
* Tries to load from session store first, then from service key store.
|
|
44
57
|
* @param destination Destination name (e.g., "TRIAL")
|
|
45
58
|
* @returns Promise that resolves to SAP URL string, or undefined if not found
|
|
46
59
|
*/
|
|
47
60
|
getSapUrl(destination: string): Promise<string | undefined>;
|
|
48
|
-
/**
|
|
49
|
-
* Save token to {destination}.env file
|
|
50
|
-
* Creates .env file similar to sap-abap-auth utility format
|
|
51
|
-
* @private
|
|
52
|
-
*/
|
|
53
|
-
private saveTokenToEnv;
|
|
54
|
-
/**
|
|
55
|
-
* Get token expiry information from JWT token
|
|
56
|
-
* @private
|
|
57
|
-
*/
|
|
58
|
-
private getTokenExpiry;
|
|
59
61
|
/**
|
|
60
62
|
* Clear cached token for specific destination
|
|
61
63
|
* @param destination Destination name
|
|
@@ -65,5 +67,10 @@ export declare class AuthBroker {
|
|
|
65
67
|
* Clear all cached tokens
|
|
66
68
|
*/
|
|
67
69
|
clearAllCache(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Get search paths for error messages (from file stores if available)
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
private getSearchPathsForError;
|
|
68
75
|
}
|
|
69
76
|
//# sourceMappingURL=AuthBroker.d.ts.map
|
package/dist/AuthBroker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"AuthBroker.d.ts","sourceRoot":"","sources":["../src/AuthBroker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,MAAM,EAAiB,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGpE;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,YAAY,CAAe;IAEnC;;;;;;;;;;;;;;OAcG;gBAED,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG;QAAE,eAAe,CAAC,EAAE,eAAe,CAAC;QAAC,YAAY,CAAC,EAAE,YAAY,CAAA;KAAE,EAC5G,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM;IAmBjB;;;;;;OAMG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgDpD;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBxD;;;OAGG;YACW,oBAAoB;IAuDlC;;;;;OAKG;IACG,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiBjE;;;OAGG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;CAW/B"}
|
package/dist/AuthBroker.js
CHANGED
|
@@ -2,50 +2,15 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Main AuthBroker class for managing JWT tokens based on destinations
|
|
4
4
|
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
6
|
exports.AuthBroker = void 0;
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const serviceKeyLoader_1 = require("./serviceKeyLoader");
|
|
7
|
+
const tokenValidator_1 = require("./tokenValidator");
|
|
8
|
+
const tokenRefresher_1 = require("./tokenRefresher");
|
|
9
|
+
const browserAuth_1 = require("./browserAuth");
|
|
44
10
|
const cache_1 = require("./cache");
|
|
45
11
|
const pathResolver_1 = require("./pathResolver");
|
|
46
12
|
const logger_1 = require("./logger");
|
|
47
|
-
const
|
|
48
|
-
const getToken_1 = require("./getToken");
|
|
13
|
+
const stores_1 = require("./stores");
|
|
49
14
|
/**
|
|
50
15
|
* AuthBroker manages JWT authentication tokens for destinations
|
|
51
16
|
*/
|
|
@@ -53,34 +18,88 @@ class AuthBroker {
|
|
|
53
18
|
searchPaths;
|
|
54
19
|
browser;
|
|
55
20
|
logger;
|
|
21
|
+
serviceKeyStore;
|
|
22
|
+
sessionStore;
|
|
56
23
|
/**
|
|
57
24
|
* Create a new AuthBroker instance
|
|
58
|
-
* @param
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
25
|
+
* @param searchPathsOrStores Optional search paths for .env and .json files (backward compatibility),
|
|
26
|
+
* OR object with custom stores.
|
|
27
|
+
* If string/array: creates default file-based stores with these paths.
|
|
28
|
+
* If object: uses provided stores (searchPaths ignored).
|
|
29
|
+
* Priority for searchPaths:
|
|
30
|
+
* 1. Constructor parameter (highest)
|
|
31
|
+
* 2. AUTH_BROKER_PATH environment variable (colon/semicolon-separated)
|
|
32
|
+
* 3. Current working directory (lowest)
|
|
64
33
|
* @param browser Optional browser name for authentication (chrome, edge, firefox, system, none).
|
|
65
34
|
* Default: 'system' (system default browser).
|
|
66
35
|
* Use 'none' to print URL instead of opening browser.
|
|
67
36
|
* @param logger Optional logger instance. If not provided, uses default logger.
|
|
68
37
|
*/
|
|
69
|
-
constructor(
|
|
70
|
-
|
|
38
|
+
constructor(searchPathsOrStores, browser, logger) {
|
|
39
|
+
// Handle backward compatibility: if first param is string/array, treat as searchPaths
|
|
40
|
+
if (typeof searchPathsOrStores === 'string' || Array.isArray(searchPathsOrStores) || searchPathsOrStores === undefined) {
|
|
41
|
+
this.searchPaths = (0, pathResolver_1.resolveSearchPaths)(searchPathsOrStores);
|
|
42
|
+
// Create default file-based stores
|
|
43
|
+
this.serviceKeyStore = new stores_1.FileServiceKeyStore(this.searchPaths);
|
|
44
|
+
this.sessionStore = new stores_1.FileSessionStore(this.searchPaths);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// New API: stores provided
|
|
48
|
+
this.searchPaths = (0, pathResolver_1.resolveSearchPaths)(undefined); // Still resolve for backward compatibility in internal functions
|
|
49
|
+
this.serviceKeyStore = searchPathsOrStores.serviceKeyStore || new stores_1.FileServiceKeyStore();
|
|
50
|
+
this.sessionStore = searchPathsOrStores.sessionStore || new stores_1.FileSessionStore();
|
|
51
|
+
}
|
|
71
52
|
this.browser = browser || 'system';
|
|
72
53
|
this.logger = logger || logger_1.defaultLogger;
|
|
73
54
|
}
|
|
74
55
|
/**
|
|
75
56
|
* Get authentication token for destination.
|
|
76
|
-
* Tries to load from
|
|
57
|
+
* Tries to load from session store, validates it, and refreshes if needed.
|
|
77
58
|
* @param destination Destination name (e.g., "TRIAL")
|
|
78
59
|
* @returns Promise that resolves to JWT token string
|
|
79
|
-
* @throws Error if neither
|
|
60
|
+
* @throws Error if neither session data nor service key found
|
|
80
61
|
*/
|
|
81
62
|
async getToken(destination) {
|
|
82
|
-
//
|
|
83
|
-
|
|
63
|
+
// Check cache first
|
|
64
|
+
const cachedToken = (0, cache_1.getCachedToken)(destination);
|
|
65
|
+
if (cachedToken) {
|
|
66
|
+
// Validate cached token
|
|
67
|
+
const envConfig = await this.sessionStore.loadSession(destination);
|
|
68
|
+
if (envConfig) {
|
|
69
|
+
const isValid = await (0, tokenValidator_1.validateToken)(cachedToken, envConfig.sapUrl);
|
|
70
|
+
if (isValid) {
|
|
71
|
+
return cachedToken;
|
|
72
|
+
}
|
|
73
|
+
// Token expired, remove from cache
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Load from session store
|
|
77
|
+
const envConfig = await this.sessionStore.loadSession(destination);
|
|
78
|
+
if (envConfig && envConfig.jwtToken) {
|
|
79
|
+
// Validate token
|
|
80
|
+
const isValid = await (0, tokenValidator_1.validateToken)(envConfig.jwtToken, envConfig.sapUrl);
|
|
81
|
+
if (isValid) {
|
|
82
|
+
(0, cache_1.setCachedToken)(destination, envConfig.jwtToken);
|
|
83
|
+
return envConfig.jwtToken;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Token not found or expired, check if we have service key for browser auth
|
|
87
|
+
const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
|
|
88
|
+
if (!serviceKey) {
|
|
89
|
+
// No service key and no valid token - throw error with helpful message
|
|
90
|
+
const searchPaths = this.getSearchPathsForError();
|
|
91
|
+
const searchedPaths = searchPaths.map(p => ` - ${p}`).join('\n');
|
|
92
|
+
throw new Error(`No authentication found for destination "${destination}". ` +
|
|
93
|
+
`Neither ${destination}.env file nor ${destination}.json service key found.\n` +
|
|
94
|
+
`Please create one of:\n` +
|
|
95
|
+
` - ${destination}.env (with SAP_JWT_TOKEN)\n` +
|
|
96
|
+
` - ${destination}.json (service key)\n` +
|
|
97
|
+
`Searched in:\n${searchedPaths}`);
|
|
98
|
+
}
|
|
99
|
+
// Try to refresh (will use browser auth if no refresh token)
|
|
100
|
+
const newToken = await this.refreshTokenInternal(destination, serviceKey, envConfig);
|
|
101
|
+
(0, cache_1.setCachedToken)(destination, newToken);
|
|
102
|
+
return newToken;
|
|
84
103
|
}
|
|
85
104
|
/**
|
|
86
105
|
* Force refresh token for destination using service key.
|
|
@@ -89,139 +108,81 @@ class AuthBroker {
|
|
|
89
108
|
* @returns Promise that resolves to new JWT token string
|
|
90
109
|
*/
|
|
91
110
|
async refreshToken(destination) {
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*/
|
|
101
|
-
async getSapUrl(destination) {
|
|
102
|
-
// Try to load from .env file first
|
|
103
|
-
const envConfig = await (0, envLoader_1.loadEnvFile)(destination, this.searchPaths);
|
|
104
|
-
if (envConfig?.sapUrl) {
|
|
105
|
-
return envConfig.sapUrl;
|
|
106
|
-
}
|
|
107
|
-
// Try service key
|
|
108
|
-
const serviceKey = await (0, serviceKeyLoader_1.loadServiceKey)(destination, this.searchPaths);
|
|
109
|
-
if (serviceKey) {
|
|
110
|
-
return serviceKey.url || serviceKey.abap?.url || serviceKey.sap_url;
|
|
111
|
+
// Load service key
|
|
112
|
+
const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
|
|
113
|
+
if (!serviceKey) {
|
|
114
|
+
const searchPaths = this.getSearchPathsForError();
|
|
115
|
+
const searchedPaths = searchPaths.map(p => ` - ${p}`).join('\n');
|
|
116
|
+
throw new Error(`Service key file not found for destination "${destination}".\n` +
|
|
117
|
+
`Please create file: ${destination}.json\n` +
|
|
118
|
+
`Searched in:\n${searchedPaths}`);
|
|
111
119
|
}
|
|
112
|
-
|
|
120
|
+
// Load existing session (for refresh token)
|
|
121
|
+
const envConfig = await this.sessionStore.loadSession(destination);
|
|
122
|
+
return this.refreshTokenInternal(destination, serviceKey, envConfig);
|
|
113
123
|
}
|
|
114
124
|
/**
|
|
115
|
-
*
|
|
116
|
-
* Creates .env file similar to sap-abap-auth utility format
|
|
125
|
+
* Internal refresh token implementation
|
|
117
126
|
* @private
|
|
118
127
|
*/
|
|
119
|
-
async
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
async refreshTokenInternal(destination, serviceKey, envConfig) {
|
|
129
|
+
// Extract UAA configuration
|
|
130
|
+
const { url: uaaUrl, clientid: clientId, clientsecret: clientSecret } = serviceKey.uaa;
|
|
131
|
+
if (!uaaUrl || !clientId || !clientSecret) {
|
|
132
|
+
throw new Error(`Invalid service key for destination "${destination}". ` +
|
|
133
|
+
`Missing required UAA fields: url, clientid, clientsecret`);
|
|
123
134
|
}
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// Add token expiry information if we can decode JWT
|
|
130
|
-
const jwtExpiry = this.getTokenExpiry(config.jwtToken);
|
|
131
|
-
const refreshExpiry = config.refreshToken ? this.getTokenExpiry(config.refreshToken) : null;
|
|
132
|
-
if (jwtExpiry || refreshExpiry) {
|
|
133
|
-
envLines.push('# Token Expiry Information (auto-generated)');
|
|
134
|
-
if (jwtExpiry) {
|
|
135
|
-
envLines.push(`# JWT Token expires: ${jwtExpiry.readableDate} (UTC)`);
|
|
136
|
-
envLines.push(`# JWT Token expires at: ${jwtExpiry.dateString}`);
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
envLines.push('# JWT Token expiry: Unable to determine (token may not be a standard JWT)');
|
|
140
|
-
}
|
|
141
|
-
if (refreshExpiry) {
|
|
142
|
-
envLines.push(`# Refresh Token expires: ${refreshExpiry.readableDate} (UTC)`);
|
|
143
|
-
envLines.push(`# Refresh Token expires at: ${refreshExpiry.dateString}`);
|
|
144
|
-
}
|
|
145
|
-
else if (config.refreshToken) {
|
|
146
|
-
envLines.push('# Refresh Token expiry: Unable to determine (token may not be a standard JWT)');
|
|
147
|
-
}
|
|
148
|
-
envLines.push('');
|
|
149
|
-
}
|
|
150
|
-
// Write JWT auth parameters (similar to sap-abap-auth format)
|
|
151
|
-
// Required fields
|
|
152
|
-
envLines.push(`SAP_URL=${config.sapUrl}`);
|
|
153
|
-
if (config.sapClient) {
|
|
154
|
-
envLines.push(`SAP_CLIENT=${config.sapClient}`);
|
|
155
|
-
}
|
|
156
|
-
if (config.language) {
|
|
157
|
-
envLines.push(`SAP_LANGUAGE=${config.language}`);
|
|
135
|
+
// Validate SAP URL early (before starting browser auth or refresh)
|
|
136
|
+
const sapUrl = serviceKey.url || serviceKey.abap?.url || serviceKey.sap_url;
|
|
137
|
+
if (!sapUrl) {
|
|
138
|
+
throw new Error(`Service key for destination "${destination}" does not contain SAP URL. ` +
|
|
139
|
+
`Expected field: url, abap.url, or sap_url`);
|
|
158
140
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
141
|
+
// Try to load existing refresh token from session store
|
|
142
|
+
let refreshTokenValue = envConfig?.refreshToken;
|
|
143
|
+
let result;
|
|
144
|
+
// If no refresh token, start browser authentication flow
|
|
145
|
+
if (!refreshTokenValue) {
|
|
146
|
+
this.logger.debug(`No refresh token found for destination "${destination}". Starting browser authentication...`);
|
|
147
|
+
result = await (0, browserAuth_1.startBrowserAuth)(serviceKey, this.browser || 'system', this.logger);
|
|
164
148
|
}
|
|
165
|
-
|
|
166
|
-
|
|
149
|
+
else {
|
|
150
|
+
// Refresh token using refresh token
|
|
151
|
+
result = await (0, tokenRefresher_1.refreshJwtToken)(refreshTokenValue, uaaUrl, clientId, clientSecret);
|
|
167
152
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
//
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
fs.renameSync(tempFilePath, envFilePath);
|
|
153
|
+
// Save new token to session store
|
|
154
|
+
await this.sessionStore.saveSession(destination, {
|
|
155
|
+
sapUrl,
|
|
156
|
+
jwtToken: result.accessToken,
|
|
157
|
+
refreshToken: result.refreshToken || refreshTokenValue,
|
|
158
|
+
uaaUrl,
|
|
159
|
+
uaaClientId: clientId,
|
|
160
|
+
uaaClientSecret: clientSecret,
|
|
161
|
+
sapClient: envConfig?.sapClient,
|
|
162
|
+
language: envConfig?.language,
|
|
163
|
+
});
|
|
164
|
+
// Update cache with new token
|
|
165
|
+
(0, cache_1.setCachedToken)(destination, result.accessToken);
|
|
166
|
+
return result.accessToken;
|
|
183
167
|
}
|
|
184
168
|
/**
|
|
185
|
-
* Get
|
|
186
|
-
*
|
|
169
|
+
* Get SAP URL for destination.
|
|
170
|
+
* Tries to load from session store first, then from service key store.
|
|
171
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
172
|
+
* @returns Promise that resolves to SAP URL string, or undefined if not found
|
|
187
173
|
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
// Decode payload (base64url)
|
|
196
|
-
const payload = parts[1];
|
|
197
|
-
// Add padding if needed
|
|
198
|
-
const padded = payload + '='.repeat((4 - payload.length % 4) % 4);
|
|
199
|
-
const decoded = Buffer.from(padded.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf8');
|
|
200
|
-
const parsed = JSON.parse(decoded);
|
|
201
|
-
// Check for exp claim
|
|
202
|
-
if (parsed.exp) {
|
|
203
|
-
const expiryDate = new Date(parsed.exp * 1000);
|
|
204
|
-
const readableDate = expiryDate.toLocaleString('en-US', {
|
|
205
|
-
weekday: 'long',
|
|
206
|
-
year: 'numeric',
|
|
207
|
-
month: 'long',
|
|
208
|
-
day: 'numeric',
|
|
209
|
-
hour: '2-digit',
|
|
210
|
-
minute: '2-digit',
|
|
211
|
-
second: '2-digit',
|
|
212
|
-
timeZone: 'UTC',
|
|
213
|
-
timeZoneName: 'short',
|
|
214
|
-
});
|
|
215
|
-
return {
|
|
216
|
-
dateString: expiryDate.toISOString(),
|
|
217
|
-
readableDate: readableDate,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
return null;
|
|
174
|
+
async getSapUrl(destination) {
|
|
175
|
+
// Try to load from session store first
|
|
176
|
+
const envConfig = await this.sessionStore.loadSession(destination);
|
|
177
|
+
if (envConfig?.sapUrl) {
|
|
178
|
+
return envConfig.sapUrl;
|
|
221
179
|
}
|
|
222
|
-
|
|
223
|
-
|
|
180
|
+
// Try service key store
|
|
181
|
+
const serviceKey = await this.serviceKeyStore.getServiceKey(destination);
|
|
182
|
+
if (serviceKey) {
|
|
183
|
+
return serviceKey.url || serviceKey.abap?.url || serviceKey.sap_url;
|
|
224
184
|
}
|
|
185
|
+
return undefined;
|
|
225
186
|
}
|
|
226
187
|
/**
|
|
227
188
|
* Clear cached token for specific destination
|
|
@@ -236,5 +197,20 @@ class AuthBroker {
|
|
|
236
197
|
clearAllCache() {
|
|
237
198
|
(0, cache_1.clearAllCache)();
|
|
238
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Get search paths for error messages (from file stores if available)
|
|
202
|
+
* @private
|
|
203
|
+
*/
|
|
204
|
+
getSearchPathsForError() {
|
|
205
|
+
// Try to get search paths from file stores
|
|
206
|
+
if (this.serviceKeyStore instanceof stores_1.FileServiceKeyStore) {
|
|
207
|
+
return this.serviceKeyStore.getSearchPaths();
|
|
208
|
+
}
|
|
209
|
+
if (this.sessionStore instanceof stores_1.FileSessionStore) {
|
|
210
|
+
return this.sessionStore.getSearchPaths();
|
|
211
|
+
}
|
|
212
|
+
// Fallback to stored searchPaths (for backward compatibility)
|
|
213
|
+
return this.searchPaths;
|
|
214
|
+
}
|
|
239
215
|
}
|
|
240
216
|
exports.AuthBroker = AuthBroker;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
export { AuthBroker } from './AuthBroker';
|
|
6
6
|
export type { EnvConfig, ServiceKey } from './types';
|
|
7
7
|
export { resolveSearchPaths, findFileInPaths } from './pathResolver';
|
|
8
|
+
export { ServiceKeyStore, SessionStore } from './stores/interfaces';
|
|
9
|
+
export { FileServiceKeyStore, FileSessionStore } from './stores';
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
* JWT authentication broker for MCP ABAP ADT server
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.findFileInPaths = exports.resolveSearchPaths = exports.AuthBroker = void 0;
|
|
7
|
+
exports.FileSessionStore = exports.FileServiceKeyStore = exports.findFileInPaths = exports.resolveSearchPaths = 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
10
|
var pathResolver_1 = require("./pathResolver");
|
|
11
11
|
Object.defineProperty(exports, "resolveSearchPaths", { enumerable: true, get: function () { return pathResolver_1.resolveSearchPaths; } });
|
|
12
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; } });
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based implementation of ServiceKeyStore
|
|
3
|
+
*
|
|
4
|
+
* Reads service keys from {destination}.json files in search paths.
|
|
5
|
+
*/
|
|
6
|
+
import { ServiceKeyStore } from './interfaces';
|
|
7
|
+
import { ServiceKey } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* File-based service key store implementation
|
|
10
|
+
*
|
|
11
|
+
* Searches for {destination}.json files in configured search paths.
|
|
12
|
+
* Search paths priority:
|
|
13
|
+
* 1. Constructor parameter (highest)
|
|
14
|
+
* 2. AUTH_BROKER_PATH environment variable
|
|
15
|
+
* 3. Current working directory (lowest)
|
|
16
|
+
*/
|
|
17
|
+
export declare class FileServiceKeyStore implements ServiceKeyStore {
|
|
18
|
+
private searchPaths;
|
|
19
|
+
/**
|
|
20
|
+
* Create a new FileServiceKeyStore instance
|
|
21
|
+
* @param searchPaths Optional search paths for .json files.
|
|
22
|
+
* Can be a single path (string) or array of paths.
|
|
23
|
+
* If not provided, uses AUTH_BROKER_PATH env var or current working directory.
|
|
24
|
+
*/
|
|
25
|
+
constructor(searchPaths?: string | string[]);
|
|
26
|
+
/**
|
|
27
|
+
* Get service key for destination
|
|
28
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
29
|
+
* @returns ServiceKey object or null if not found
|
|
30
|
+
*/
|
|
31
|
+
getServiceKey(destination: string): Promise<ServiceKey | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Get search paths (for error messages)
|
|
34
|
+
* @returns Array of search paths
|
|
35
|
+
*/
|
|
36
|
+
getSearchPaths(): string[];
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=FileServiceKeyStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileServiceKeyStore.d.ts","sourceRoot":"","sources":["../../src/stores/FileServiceKeyStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAItC;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,WAAW,CAAW;IAE9B;;;;;OAKG;gBACS,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAI3C;;;;OAIG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIpE;;;OAGG;IACH,cAAc,IAAI,MAAM,EAAE;CAG3B"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* File-based implementation of ServiceKeyStore
|
|
4
|
+
*
|
|
5
|
+
* Reads service keys from {destination}.json files in search paths.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.FileServiceKeyStore = void 0;
|
|
9
|
+
const serviceKeyLoader_1 = require("../serviceKeyLoader");
|
|
10
|
+
const pathResolver_1 = require("../pathResolver");
|
|
11
|
+
/**
|
|
12
|
+
* File-based service key store implementation
|
|
13
|
+
*
|
|
14
|
+
* Searches for {destination}.json files in configured search paths.
|
|
15
|
+
* Search paths priority:
|
|
16
|
+
* 1. Constructor parameter (highest)
|
|
17
|
+
* 2. AUTH_BROKER_PATH environment variable
|
|
18
|
+
* 3. Current working directory (lowest)
|
|
19
|
+
*/
|
|
20
|
+
class FileServiceKeyStore {
|
|
21
|
+
searchPaths;
|
|
22
|
+
/**
|
|
23
|
+
* Create a new FileServiceKeyStore instance
|
|
24
|
+
* @param searchPaths Optional search paths for .json files.
|
|
25
|
+
* Can be a single path (string) or array of paths.
|
|
26
|
+
* If not provided, uses AUTH_BROKER_PATH env var or current working directory.
|
|
27
|
+
*/
|
|
28
|
+
constructor(searchPaths) {
|
|
29
|
+
this.searchPaths = (0, pathResolver_1.resolveSearchPaths)(searchPaths);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get service key for destination
|
|
33
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
34
|
+
* @returns ServiceKey object or null if not found
|
|
35
|
+
*/
|
|
36
|
+
async getServiceKey(destination) {
|
|
37
|
+
return (0, serviceKeyLoader_1.loadServiceKey)(destination, this.searchPaths);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get search paths (for error messages)
|
|
41
|
+
* @returns Array of search paths
|
|
42
|
+
*/
|
|
43
|
+
getSearchPaths() {
|
|
44
|
+
return [...this.searchPaths];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.FileServiceKeyStore = FileServiceKeyStore;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based implementation of SessionStore
|
|
3
|
+
*
|
|
4
|
+
* Reads/writes session data from/to {destination}.env files in search paths.
|
|
5
|
+
*/
|
|
6
|
+
import { SessionStore } from './interfaces';
|
|
7
|
+
import { EnvConfig } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* File-based session store implementation
|
|
10
|
+
*
|
|
11
|
+
* Searches for {destination}.env files in configured search paths.
|
|
12
|
+
* Writes to first search path (highest priority).
|
|
13
|
+
* Search paths priority:
|
|
14
|
+
* 1. Constructor parameter (highest)
|
|
15
|
+
* 2. AUTH_BROKER_PATH environment variable
|
|
16
|
+
* 3. Current working directory (lowest)
|
|
17
|
+
*/
|
|
18
|
+
export declare class FileSessionStore implements SessionStore {
|
|
19
|
+
private searchPaths;
|
|
20
|
+
/**
|
|
21
|
+
* Create a new FileSessionStore instance
|
|
22
|
+
* @param searchPaths Optional search paths for .env files.
|
|
23
|
+
* Can be a single path (string) or array of paths.
|
|
24
|
+
* If not provided, uses AUTH_BROKER_PATH env var or current working directory.
|
|
25
|
+
*/
|
|
26
|
+
constructor(searchPaths?: string | string[]);
|
|
27
|
+
/**
|
|
28
|
+
* Load session configuration for destination
|
|
29
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
30
|
+
* @returns EnvConfig object or null if not found
|
|
31
|
+
*/
|
|
32
|
+
loadSession(destination: string): Promise<EnvConfig | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Save session configuration for destination
|
|
35
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
36
|
+
* @param config Session configuration to save
|
|
37
|
+
*/
|
|
38
|
+
saveSession(destination: string, config: EnvConfig): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Delete session for destination
|
|
41
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
42
|
+
*/
|
|
43
|
+
deleteSession(destination: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Get search paths (for error messages)
|
|
46
|
+
* @returns Array of search paths
|
|
47
|
+
*/
|
|
48
|
+
getSearchPaths(): string[];
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=FileSessionStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileSessionStore.d.ts","sourceRoot":"","sources":["../../src/stores/FileSessionStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKrC;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IACnD,OAAO,CAAC,WAAW,CAAW;IAE9B;;;;;OAKG;gBACS,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAI3C;;;;OAIG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAIjE;;;;OAIG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxE;;;OAGG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvD;;;OAGG;IACH,cAAc,IAAI,MAAM,EAAE;CAG3B"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* File-based implementation of SessionStore
|
|
4
|
+
*
|
|
5
|
+
* Reads/writes session data from/to {destination}.env files in search paths.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.FileSessionStore = void 0;
|
|
42
|
+
const envLoader_1 = require("../envLoader");
|
|
43
|
+
const tokenStorage_1 = require("../tokenStorage");
|
|
44
|
+
const pathResolver_1 = require("../pathResolver");
|
|
45
|
+
/**
|
|
46
|
+
* File-based session store implementation
|
|
47
|
+
*
|
|
48
|
+
* Searches for {destination}.env files in configured search paths.
|
|
49
|
+
* Writes to first search path (highest priority).
|
|
50
|
+
* Search paths priority:
|
|
51
|
+
* 1. Constructor parameter (highest)
|
|
52
|
+
* 2. AUTH_BROKER_PATH environment variable
|
|
53
|
+
* 3. Current working directory (lowest)
|
|
54
|
+
*/
|
|
55
|
+
class FileSessionStore {
|
|
56
|
+
searchPaths;
|
|
57
|
+
/**
|
|
58
|
+
* Create a new FileSessionStore instance
|
|
59
|
+
* @param searchPaths Optional search paths for .env files.
|
|
60
|
+
* Can be a single path (string) or array of paths.
|
|
61
|
+
* If not provided, uses AUTH_BROKER_PATH env var or current working directory.
|
|
62
|
+
*/
|
|
63
|
+
constructor(searchPaths) {
|
|
64
|
+
this.searchPaths = (0, pathResolver_1.resolveSearchPaths)(searchPaths);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Load session configuration for destination
|
|
68
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
69
|
+
* @returns EnvConfig object or null if not found
|
|
70
|
+
*/
|
|
71
|
+
async loadSession(destination) {
|
|
72
|
+
return (0, envLoader_1.loadEnvFile)(destination, this.searchPaths);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Save session configuration for destination
|
|
76
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
77
|
+
* @param config Session configuration to save
|
|
78
|
+
*/
|
|
79
|
+
async saveSession(destination, config) {
|
|
80
|
+
// Save to first search path (highest priority)
|
|
81
|
+
const savePath = this.searchPaths[0];
|
|
82
|
+
// Convert EnvConfig to format expected by saveTokenToEnv
|
|
83
|
+
await (0, tokenStorage_1.saveTokenToEnv)(destination, savePath, {
|
|
84
|
+
sapUrl: config.sapUrl,
|
|
85
|
+
jwtToken: config.jwtToken,
|
|
86
|
+
refreshToken: config.refreshToken,
|
|
87
|
+
uaaUrl: config.uaaUrl,
|
|
88
|
+
uaaClientId: config.uaaClientId,
|
|
89
|
+
uaaClientSecret: config.uaaClientSecret,
|
|
90
|
+
sapClient: config.sapClient,
|
|
91
|
+
language: config.language,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Delete session for destination
|
|
96
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
97
|
+
*/
|
|
98
|
+
async deleteSession(destination) {
|
|
99
|
+
// Find .env file in search paths
|
|
100
|
+
const fileName = `${destination}.env`;
|
|
101
|
+
const { findFileInPaths } = await Promise.resolve().then(() => __importStar(require('../pathResolver')));
|
|
102
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
103
|
+
const envFilePath = findFileInPaths(fileName, this.searchPaths);
|
|
104
|
+
if (envFilePath && fs.existsSync(envFilePath)) {
|
|
105
|
+
fs.unlinkSync(envFilePath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get search paths (for error messages)
|
|
110
|
+
* @returns Array of search paths
|
|
111
|
+
*/
|
|
112
|
+
getSearchPaths() {
|
|
113
|
+
return [...this.searchPaths];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.FileSessionStore = FileSessionStore;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage implementations for AuthBroker
|
|
3
|
+
*/
|
|
4
|
+
export { ServiceKeyStore, SessionStore } from './interfaces';
|
|
5
|
+
export { FileServiceKeyStore } from './FileServiceKeyStore';
|
|
6
|
+
export { FileSessionStore } from './FileSessionStore';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stores/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Storage implementations for AuthBroker
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FileSessionStore = exports.FileServiceKeyStore = void 0;
|
|
7
|
+
var FileServiceKeyStore_1 = require("./FileServiceKeyStore");
|
|
8
|
+
Object.defineProperty(exports, "FileServiceKeyStore", { enumerable: true, get: function () { return FileServiceKeyStore_1.FileServiceKeyStore; } });
|
|
9
|
+
var FileSessionStore_1 = require("./FileSessionStore");
|
|
10
|
+
Object.defineProperty(exports, "FileSessionStore", { enumerable: true, get: function () { return FileSessionStore_1.FileSessionStore; } });
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage interfaces for AuthBroker
|
|
3
|
+
*
|
|
4
|
+
* These interfaces allow consumers to provide custom storage implementations
|
|
5
|
+
* for service keys and session data (tokens, configuration).
|
|
6
|
+
*/
|
|
7
|
+
import { ServiceKey, EnvConfig } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* Interface for storing and retrieving service keys
|
|
10
|
+
*
|
|
11
|
+
* Service keys contain UAA credentials and SAP URL for a destination.
|
|
12
|
+
* Default implementation: FileServiceKeyStore (reads from {destination}.json files)
|
|
13
|
+
*/
|
|
14
|
+
export interface ServiceKeyStore {
|
|
15
|
+
/**
|
|
16
|
+
* Get service key for destination
|
|
17
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
18
|
+
* @returns ServiceKey object or null if not found
|
|
19
|
+
*/
|
|
20
|
+
getServiceKey(destination: string): Promise<ServiceKey | null>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Interface for storing and retrieving session data (tokens, configuration)
|
|
24
|
+
*
|
|
25
|
+
* Session data contains JWT tokens, refresh tokens, UAA config, and SAP URL.
|
|
26
|
+
* Default implementation: FileSessionStore (reads/writes {destination}.env files)
|
|
27
|
+
*/
|
|
28
|
+
export interface SessionStore {
|
|
29
|
+
/**
|
|
30
|
+
* Load session configuration for destination
|
|
31
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
32
|
+
* @returns EnvConfig object or null if not found
|
|
33
|
+
*/
|
|
34
|
+
loadSession(destination: string): Promise<EnvConfig | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Save session configuration for destination
|
|
37
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
38
|
+
* @param config Session configuration to save
|
|
39
|
+
*/
|
|
40
|
+
saveSession(destination: string, config: EnvConfig): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Delete session for destination (optional)
|
|
43
|
+
* @param destination Destination name (e.g., "TRIAL")
|
|
44
|
+
*/
|
|
45
|
+
deleteSession?(destination: string): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/stores/interfaces.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CAChE;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAE5D;;;;OAIG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnE;;;OAGG;IACH,aAAa,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Storage interfaces for AuthBroker
|
|
4
|
+
*
|
|
5
|
+
* These interfaces allow consumers to provide custom storage implementations
|
|
6
|
+
* for service keys and session data (tokens, configuration).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/package.json
CHANGED