@mcp-abap-adt/auth-providers 0.1.0

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 ADDED
@@ -0,0 +1,50 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2024-12-04
11
+
12
+ ### Added
13
+ - Initial release
14
+ - **XsuaaTokenProvider** - Uses `client_credentials` grant type (no browser required)
15
+ - **BtpTokenProvider** - Uses browser-based OAuth2 or refresh token flow
16
+ - Browser authentication flow with OAuth2 callback server
17
+ - Client credentials authentication
18
+ - Token refresh functionality
19
+ - Token validation (`validateToken` method)
20
+ - **Integration Tests**:
21
+ - Integration tests for all providers using real files from `test-config.yaml`
22
+ - Test configuration helpers (`configHelpers.ts`) matching auth-broker format
23
+ - YAML-based test configuration (`tests/test-config.yaml.template`)
24
+ - Tests for service key to session conversion
25
+ - Tests for token validation
26
+ - BTP tests use `BtpServiceKeyStore` and `BtpSessionStore` (without `sapUrl`)
27
+ - ABAP tests use `AbapServiceKeyStore` and `AbapSessionStore` (with `sapUrl`)
28
+ - BTP tests use `xsuaa.btp_destination` from config
29
+ - ABAP tests use `abap.destination` from config
30
+
31
+ ### Fixed
32
+ - **Integration Tests**: Corrected BTP and ABAP test separation
33
+ - BTP tests correctly handle base BTP sessions (no `sapUrl` required)
34
+ - ABAP tests correctly handle ABAP sessions (with `sapUrl` from service key)
35
+ - **Token Validation**: BTP tests now handle cases where `serviceUrl` may not be available (base BTP)
36
+ - **Session Storage**: BTP tests no longer attempt to save `serviceUrl` to `BtpSessionStore` (which doesn't accept `sapUrl`)
37
+
38
+ ### Changed
39
+ - **Documentation**: Updated README to clarify BTP vs ABAP differences and correct store usage
40
+ - Added explicit examples showing BTP and ABAP as separate entities
41
+ - Clarified that BTP uses `BtpServiceKeyStore`/`BtpSessionStore` (without `sapUrl`)
42
+ - Clarified that ABAP uses `AbapServiceKeyStore`/`AbapSessionStore` (with `sapUrl`)
43
+ - Updated integration test configuration examples
44
+
45
+ ### Dependencies
46
+ - `@mcp-abap-adt/auth-broker` ^0.1.6 - Interface definitions
47
+ - `@mcp-abap-adt/auth-stores` ^0.1.2 - Store implementations
48
+ - `@mcp-abap-adt/connection` ^0.1.13 - Connection utilities
49
+ - `@mcp-abap-adt/logger` ^0.1.0 - Logging utilities
50
+
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Oleksii Kyslytsia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # @mcp-abap-adt/auth-providers
2
+
3
+ Token providers for MCP ABAP ADT auth-broker - XSUAA and BTP token providers.
4
+
5
+ This package provides token provider implementations for the `@mcp-abap-adt/auth-broker` package.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @mcp-abap-adt/auth-providers
11
+ ```
12
+
13
+ ## Overview
14
+
15
+ This package implements the `ITokenProvider` interface from `@mcp-abap-adt/auth-broker`:
16
+
17
+ - **XsuaaTokenProvider** - Uses `client_credentials` grant type (no browser required)
18
+ - **BtpTokenProvider** - Uses browser-based OAuth2 or refresh token flow
19
+
20
+ ## Usage
21
+
22
+ ### Basic Usage
23
+
24
+ ```typescript
25
+ import { AuthBroker } from '@mcp-abap-adt/auth-broker';
26
+ import { XsuaaTokenProvider, BtpTokenProvider } from '@mcp-abap-adt/auth-providers';
27
+
28
+ // Use XSUAA provider (client_credentials)
29
+ const xsuaaBroker = new AuthBroker({
30
+ tokenProvider: new XsuaaTokenProvider(),
31
+ }, 'none'); // Browser not needed
32
+
33
+ // Use BTP provider (browser OAuth2 or refresh token)
34
+ const btpBroker = new AuthBroker({
35
+ tokenProvider: new BtpTokenProvider(),
36
+ });
37
+ ```
38
+
39
+ ### With Stores
40
+
41
+ **Important**: BTP and ABAP are different entities:
42
+ - **BTP** (base BTP) - uses `BtpServiceKeyStore` and `BtpSessionStore` (without `sapUrl`)
43
+ - **ABAP** - uses `AbapServiceKeyStore` and `AbapSessionStore` (with `sapUrl`)
44
+
45
+ ```typescript
46
+ import { AuthBroker } from '@mcp-abap-adt/auth-broker';
47
+ import { XsuaaTokenProvider, BtpTokenProvider } from '@mcp-abap-adt/auth-providers';
48
+ import {
49
+ XsuaaServiceKeyStore,
50
+ XsuaaSessionStore,
51
+ BtpServiceKeyStore,
52
+ BtpSessionStore,
53
+ AbapServiceKeyStore,
54
+ AbapSessionStore
55
+ } from '@mcp-abap-adt/auth-stores';
56
+
57
+ // XSUAA provider with stores
58
+ const xsuaaServiceKeyStore = new XsuaaServiceKeyStore('/path/to/service-keys');
59
+ const xsuaaSessionStore = new XsuaaSessionStore('/path/to/sessions');
60
+
61
+ const xsuaaBroker = new AuthBroker({
62
+ serviceKeyStore: xsuaaServiceKeyStore,
63
+ sessionStore: xsuaaSessionStore,
64
+ tokenProvider: new XsuaaTokenProvider(),
65
+ }, 'none');
66
+
67
+ // BTP provider with stores (base BTP, without sapUrl)
68
+ const btpServiceKeyStore = new BtpServiceKeyStore('/path/to/service-keys');
69
+ const btpSessionStore = new BtpSessionStore('/path/to/sessions');
70
+
71
+ const btpBroker = new AuthBroker({
72
+ serviceKeyStore: btpServiceKeyStore,
73
+ sessionStore: btpSessionStore,
74
+ tokenProvider: new BtpTokenProvider(),
75
+ });
76
+
77
+ // ABAP provider with stores (with sapUrl)
78
+ const abapServiceKeyStore = new AbapServiceKeyStore('/path/to/service-keys');
79
+ const abapSessionStore = new AbapSessionStore('/path/to/sessions');
80
+
81
+ const abapBroker = new AuthBroker({
82
+ serviceKeyStore: abapServiceKeyStore,
83
+ sessionStore: abapSessionStore,
84
+ tokenProvider: new BtpTokenProvider(), // BtpTokenProvider works for ABAP too
85
+ });
86
+ ```
87
+
88
+ ### Token Providers
89
+
90
+ #### XsuaaTokenProvider
91
+
92
+ Uses `client_credentials` grant type - no browser interaction required:
93
+
94
+ ```typescript
95
+ import { XsuaaTokenProvider } from '@mcp-abap-adt/auth-providers';
96
+ import type { IAuthorizationConfig } from '@mcp-abap-adt/auth-broker';
97
+
98
+ const provider = new XsuaaTokenProvider();
99
+
100
+ const authConfig: IAuthorizationConfig = {
101
+ uaaUrl: 'https://...authentication...hana.ondemand.com',
102
+ uaaClientId: '...',
103
+ uaaClientSecret: '...',
104
+ };
105
+
106
+ const result = await provider.getConnectionConfig(authConfig, {
107
+ logger: defaultLogger,
108
+ });
109
+
110
+ // result.connectionConfig.authorizationToken contains the JWT token
111
+ // result.refreshToken is undefined (client_credentials doesn't provide refresh tokens)
112
+ ```
113
+
114
+ #### BtpTokenProvider
115
+
116
+ Uses browser-based OAuth2 flow or refresh token:
117
+
118
+ ```typescript
119
+ import { BtpTokenProvider } from '@mcp-abap-adt/auth-providers';
120
+ import type { IAuthorizationConfig } from '@mcp-abap-adt/auth-broker';
121
+
122
+ const provider = new BtpTokenProvider();
123
+
124
+ const authConfig: IAuthorizationConfig = {
125
+ uaaUrl: 'https://...authentication...hana.ondemand.com',
126
+ uaaClientId: '...',
127
+ uaaClientSecret: '...',
128
+ refreshToken: '...', // Optional - if provided, uses refresh flow instead of browser
129
+ };
130
+
131
+ // If refreshToken is provided, uses refresh flow (no browser)
132
+ // Otherwise, opens browser for OAuth2 authorization
133
+ const result = await provider.getConnectionConfig(authConfig, {
134
+ logger: defaultLogger,
135
+ browser: 'system', // 'system', 'none', or undefined
136
+ });
137
+
138
+ // result.connectionConfig.authorizationToken contains the JWT token
139
+ // result.refreshToken contains refresh token (if browser flow was used)
140
+ ```
141
+
142
+ ### Token Validation
143
+
144
+ Both providers support token validation:
145
+
146
+ ```typescript
147
+ const isValid = await provider.validateToken(token, serviceUrl);
148
+ // Returns true if token is valid (200-299 status), false otherwise
149
+ ```
150
+
151
+ ## Testing
152
+
153
+ The package includes both unit tests (with mocks) and integration tests (with real files and services).
154
+
155
+ ### Unit Tests
156
+
157
+ ```bash
158
+ npm test
159
+ ```
160
+
161
+ ### Integration Tests
162
+
163
+ Integration tests work with real files from `tests/test-config.yaml`:
164
+
165
+ 1. Copy `tests/test-config.yaml.template` to `tests/test-config.yaml`
166
+ 2. Fill in real paths, destinations, and URLs
167
+ 3. Run tests - integration tests will use real services if configured
168
+
169
+ ```yaml
170
+ auth_broker:
171
+ paths:
172
+ service_keys_dir: ~/.config/mcp-abap-adt/service-keys/
173
+ sessions_dir: ~/.config/mcp-abap-adt/sessions/
174
+ abap:
175
+ destination: "TRIAL" # For ABAP tests (uses AbapServiceKeyStore, AbapSessionStore)
176
+ xsuaa:
177
+ btp_destination: "mcp" # For BTP tests (uses BtpServiceKeyStore, BtpSessionStore)
178
+ mcp_url: "https://..."
179
+ ```
180
+
181
+ Integration tests will skip if `test-config.yaml` is not configured or contains placeholder values.
182
+
183
+ **Note**:
184
+ - BTP integration tests use `xsuaa.btp_destination` and require `BtpServiceKeyStore`/`BtpSessionStore` (without `sapUrl`)
185
+ - ABAP integration tests use `abap.destination` and require `AbapServiceKeyStore`/`AbapSessionStore` (with `sapUrl`)
186
+ - BTP/ABAP integration tests may open a browser for authentication if no refresh token is available. This is expected behavior.
187
+
188
+ ## Dependencies
189
+
190
+ - `@mcp-abap-adt/auth-broker` (^0.1.6) - Interface definitions
191
+ - `@mcp-abap-adt/auth-stores` (^0.1.2) - Store implementations
192
+ - `@mcp-abap-adt/connection` (^0.1.13) - Connection utilities
193
+ - `@mcp-abap-adt/logger` (^0.1.0) - Logging utilities
194
+ - `axios` - HTTP client
195
+ - `express` - OAuth2 callback server
196
+ - `open` - Browser opening utility
197
+
198
+ ## License
199
+
200
+ MIT
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Configuration helpers for auth-providers tests
3
+ * Loads test configuration from test-config.yaml (same format as auth-broker)
4
+ */
5
+ export interface TestConfig {
6
+ auth_broker?: {
7
+ paths?: {
8
+ service_keys_dir?: string;
9
+ sessions_dir?: string;
10
+ };
11
+ abap?: {
12
+ destination?: string;
13
+ };
14
+ xsuaa?: {
15
+ btp_destination?: string;
16
+ mcp_destination?: string;
17
+ mcp_url?: string;
18
+ };
19
+ };
20
+ }
21
+ /**
22
+ * Load test configuration from YAML
23
+ * Uses test-config.yaml from tests/ directory
24
+ */
25
+ export declare function loadTestConfig(): TestConfig;
26
+ /**
27
+ * Check if test config has real values (not placeholders)
28
+ */
29
+ export declare function hasRealConfig(config: TestConfig, section: 'abap' | 'xsuaa'): boolean;
30
+ /**
31
+ * Get ABAP destination from config
32
+ */
33
+ export declare function getAbapDestination(config?: TestConfig): string | null;
34
+ /**
35
+ * Get XSUAA destinations from config
36
+ */
37
+ export declare function getXsuaaDestinations(config?: TestConfig): {
38
+ btp_destination: string | null;
39
+ mcp_url: string | null;
40
+ };
41
+ /**
42
+ * Get service keys directory from config
43
+ * Expands ~ to home directory
44
+ */
45
+ export declare function getServiceKeysDir(config?: TestConfig): string | null;
46
+ /**
47
+ * Get sessions directory from config
48
+ * Expands ~ to home directory
49
+ */
50
+ export declare function getSessionsDir(config?: TestConfig): string | null;
51
+ //# sourceMappingURL=configHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configHelpers.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/configHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE;YACN,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC;QACF,IAAI,CAAC,EAAE;YACL,WAAW,CAAC,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,KAAK,CAAC,EAAE;YACN,eAAe,CAAC,EAAE,MAAM,CAAC;YACzB,eAAe,CAAC,EAAE,MAAM,CAAC;YACzB,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;KACH,CAAC;CACH;AAkBD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,CA6C3C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAwBpF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAGrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG;IACzD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAOA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAYpE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAYjE"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration helpers for auth-providers tests
4
+ * Loads test configuration from test-config.yaml (same format as auth-broker)
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.loadTestConfig = loadTestConfig;
41
+ exports.hasRealConfig = hasRealConfig;
42
+ exports.getAbapDestination = getAbapDestination;
43
+ exports.getXsuaaDestinations = getXsuaaDestinations;
44
+ exports.getServiceKeysDir = getServiceKeysDir;
45
+ exports.getSessionsDir = getSessionsDir;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const yaml = __importStar(require("js-yaml"));
49
+ let cachedConfig = null;
50
+ /**
51
+ * Find project root directory by looking for package.json
52
+ */
53
+ function findProjectRoot() {
54
+ let currentDir = __dirname;
55
+ while (currentDir !== path.dirname(currentDir)) {
56
+ const packageJsonPath = path.join(currentDir, 'package.json');
57
+ if (fs.existsSync(packageJsonPath)) {
58
+ return currentDir;
59
+ }
60
+ currentDir = path.dirname(currentDir);
61
+ }
62
+ // Fallback to process.cwd() if package.json not found
63
+ return process.cwd();
64
+ }
65
+ /**
66
+ * Load test configuration from YAML
67
+ * Uses test-config.yaml from tests/ directory
68
+ */
69
+ function loadTestConfig() {
70
+ if (cachedConfig) {
71
+ return cachedConfig;
72
+ }
73
+ // Find project root and load from tests/test-config.yaml
74
+ const projectRoot = findProjectRoot();
75
+ const configPath = path.resolve(projectRoot, 'tests', 'test-config.yaml');
76
+ const templatePath = path.resolve(projectRoot, 'tests', 'test-config.yaml.template');
77
+ if (process.env.TEST_VERBOSE) {
78
+ console.log(`[configHelpers] Project root: ${projectRoot}`);
79
+ console.log(`[configHelpers] Config path: ${configPath}`);
80
+ console.log(`[configHelpers] Config exists: ${fs.existsSync(configPath)}`);
81
+ }
82
+ if (fs.existsSync(configPath)) {
83
+ try {
84
+ const configContent = fs.readFileSync(configPath, 'utf8');
85
+ cachedConfig = yaml.load(configContent) || {};
86
+ if (process.env.TEST_VERBOSE) {
87
+ console.log(`[configHelpers] Loaded config:`, JSON.stringify(cachedConfig, null, 2));
88
+ }
89
+ return cachedConfig;
90
+ }
91
+ catch (error) {
92
+ console.warn(`Failed to load test config from ${configPath}:`, error);
93
+ return {};
94
+ }
95
+ }
96
+ if (fs.existsSync(templatePath)) {
97
+ console.warn('⚠️ tests/test-config.yaml not found. Using template (all integration tests will be disabled).');
98
+ try {
99
+ const templateContent = fs.readFileSync(templatePath, 'utf8');
100
+ cachedConfig = yaml.load(templateContent) || {};
101
+ return cachedConfig;
102
+ }
103
+ catch (error) {
104
+ console.warn(`Failed to load test config template from ${templatePath}:`, error);
105
+ return {};
106
+ }
107
+ }
108
+ console.warn('⚠️ Test configuration files not found.');
109
+ console.warn('Please create tests/test-config.yaml with test parameters.');
110
+ return {};
111
+ }
112
+ /**
113
+ * Check if test config has real values (not placeholders)
114
+ */
115
+ function hasRealConfig(config, section) {
116
+ if (!config.auth_broker) {
117
+ return false;
118
+ }
119
+ if (section === 'abap') {
120
+ const abap = config.auth_broker.abap;
121
+ if (!abap?.destination) {
122
+ return false;
123
+ }
124
+ // Check if destination is not a placeholder
125
+ return !abap.destination.includes('<') && !abap.destination.includes('>');
126
+ }
127
+ if (section === 'xsuaa') {
128
+ const xsuaa = config.auth_broker.xsuaa;
129
+ if (!xsuaa?.btp_destination) {
130
+ return false;
131
+ }
132
+ // Check if values are not placeholders
133
+ return !xsuaa.btp_destination.includes('<');
134
+ }
135
+ return false;
136
+ }
137
+ /**
138
+ * Get ABAP destination from config
139
+ */
140
+ function getAbapDestination(config) {
141
+ const cfg = config || loadTestConfig();
142
+ return cfg.auth_broker?.abap?.destination || null;
143
+ }
144
+ /**
145
+ * Get XSUAA destinations from config
146
+ */
147
+ function getXsuaaDestinations(config) {
148
+ const cfg = config || loadTestConfig();
149
+ const xsuaa = cfg.auth_broker?.xsuaa;
150
+ return {
151
+ btp_destination: xsuaa?.btp_destination || null,
152
+ mcp_url: xsuaa?.mcp_url || null,
153
+ };
154
+ }
155
+ /**
156
+ * Get service keys directory from config
157
+ * Expands ~ to home directory
158
+ */
159
+ function getServiceKeysDir(config) {
160
+ const cfg = config || loadTestConfig();
161
+ const dir = cfg.auth_broker?.paths?.service_keys_dir;
162
+ if (!dir)
163
+ return null;
164
+ // Expand ~ to home directory
165
+ if (dir.startsWith('~')) {
166
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
167
+ return dir.replace('~', homeDir);
168
+ }
169
+ return dir;
170
+ }
171
+ /**
172
+ * Get sessions directory from config
173
+ * Expands ~ to home directory
174
+ */
175
+ function getSessionsDir(config) {
176
+ const cfg = config || loadTestConfig();
177
+ const dir = cfg.auth_broker?.paths?.sessions_dir;
178
+ if (!dir)
179
+ return null;
180
+ // Expand ~ to home directory
181
+ if (dir.startsWith('~')) {
182
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
183
+ return dir.replace('~', homeDir);
184
+ }
185
+ return dir;
186
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Browser authentication - OAuth2 flow for obtaining tokens
3
+ */
4
+ import type { IAuthorizationConfig } from '@mcp-abap-adt/auth-broker';
5
+ import type { Logger } from '@mcp-abap-adt/logger';
6
+ /**
7
+ * Start browser authentication flow
8
+ * @param authConfig Authorization configuration with UAA credentials
9
+ * @param browser Browser name (chrome, edge, firefox, system, none)
10
+ * @param logger Optional logger instance. If not provided, uses default logger.
11
+ * @returns Promise that resolves to tokens
12
+ */
13
+ export declare function startBrowserAuth(authConfig: IAuthorizationConfig, browser?: string, logger?: Logger): Promise<{
14
+ accessToken: string;
15
+ refreshToken?: string;
16
+ }>;
17
+ //# sourceMappingURL=browserAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserAuth.d.ts","sourceRoot":"","sources":["../../src/auth/browserAuth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAkFnD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,oBAAoB,EAChC,OAAO,GAAE,MAAiB,EAC1B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAkSzD"}