{"_id":"@babamba2/mcp-abap-adt-auth-stores","name":"@babamba2/mcp-abap-adt-auth-stores","dist-tags":{"latest":"1.0.4"},"versions":{"1.0.4":{"name":"@babamba2/mcp-abap-adt-auth-stores","version":"1.0.4","description":"Stores for MCP ABAP ADT auth-broker - BTP, ABAP, and XSUAA implementations (fork of @mcp-abap-adt/auth-stores by fr0ster)","main":"dist/index.js","types":"dist/index.d.ts","keywords":["abap","sap","adt","jwt","authentication","token","store","btp","abap","xsuaa","mcp","abap-adt"],"author":{"name":"babamba2","email":"psspss1122@gmail.com"},"contributors":[{"name":"Oleksii Kyslytsia","email":"oleksij.kyslytsja@gmail.com","url":"original author"}],"license":"MIT","homepage":"https://github.com/babamba2/mcp-abap-adt-auth-stores#readme","bugs":{"url":"https://github.com/babamba2/mcp-abap-adt-auth-stores/issues"},"repository":{"type":"git","url":"git+https://github.com/babamba2/mcp-abap-adt-auth-stores.git"},"publishConfig":{"access":"public"},"scripts":{"chrono":"./tools/version-stats.sh","clean":"rm -rf dist tsconfig.tsbuildinfo","lint":"npx biome check --write src","lint:check":"npx biome check src","format":"npx biome format --write src","build":"npm run --silent clean && npx biome check src --diagnostic-level=error && npx tsc -p tsconfig.json","build:fast":"npx tsc -p tsconfig.json","test":"NODE_OPTIONS=--experimental-vm-modules jest","test:check":"npx tsc --noEmit","prepublishOnly":"npm run build:fast"},"engines":{"node":">=18.0.0"},"dependencies":{"@babamba2/mcp-abap-adt-interfaces":"^3.1.0","dotenv":"^17.3.1"},"devDependencies":{"@biomejs/biome":"^2.4.7","@babamba2/mcp-abap-adt-logger":"^0.1.4","@types/jest":"^30.0.0","@types/js-yaml":"^4.0.9","@types/node":"^25.5.0","jest":"^30.3.0","jest-util":"^30.3.0","js-yaml":"^4.1.1","pino":"^10.1.0","pino-pretty":"^13.1.3","ts-jest":"^29.4.6","typescript":"^5.9.2"},"gitHead":"c1b9ac69432d93ba44f84a06627c80f83ae2057c","_id":"@babamba2/mcp-abap-adt-auth-stores@1.0.4","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-XT6XvDHJOSEsfjDP/bn+pyLDn5FC3iVBGYT5ladtgR3IedE3WbgkeKXTHjW4SjHwfpUxGM94e0rAQT2onbNoYg==","shasum":"b14231dd52d7388016178642958849101e7c73aa","tarball":"https://registry.npmjs.org/@babamba2/mcp-abap-adt-auth-stores/-/mcp-abap-adt-auth-stores-1.0.4.tgz","fileCount":48,"unpackedSize":248936,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDiCy71bXpSUf32QvU25rGhHzICHjt2Ade8MARCD54MLAiA7P9dyWm6D7wsh45MXcYmm9+1Nobn/aoAC8BFAG5cflg=="}]},"_npmUser":{"name":"psspss1122","email":"psspss1122@gmail.com"},"directories":{},"maintainers":[{"name":"psspss1122","email":"psspss1122@gmail.com"},{"name":"s2hoon326","email":"s2hoon326@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-abap-adt-auth-stores_1.0.4_1776491840489_0.16517135912853287"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-18T05:57:20.378Z","1.0.4":"2026-04-18T05:57:20.681Z","modified":"2026-04-18T05:57:21.182Z"},"maintainers":[{"name":"psspss1122","email":"psspss1122@gmail.com"},{"name":"s2hoon326","email":"s2hoon326@gmail.com"}],"description":"Stores for MCP ABAP ADT auth-broker - BTP, ABAP, and XSUAA implementations (fork of @mcp-abap-adt/auth-stores by fr0ster)","homepage":"https://github.com/babamba2/mcp-abap-adt-auth-stores#readme","keywords":["abap","sap","adt","jwt","authentication","token","store","btp","abap","xsuaa","mcp","abap-adt"],"repository":{"type":"git","url":"git+https://github.com/babamba2/mcp-abap-adt-auth-stores.git"},"contributors":[{"name":"Oleksii Kyslytsia","email":"oleksij.kyslytsja@gmail.com","url":"original author"}],"author":{"name":"babamba2","email":"psspss1122@gmail.com"},"bugs":{"url":"https://github.com/babamba2/mcp-abap-adt-auth-stores/issues"},"license":"MIT","readme":"# @mcp-abap-adt/auth-stores\r\n\r\nStores for MCP ABAP ADT auth-broker - BTP, ABAP, and XSUAA implementations.\r\n\r\nThis package provides file-based and in-memory stores for service keys and sessions used by the `@mcp-abap-adt/auth-broker` package.\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @mcp-abap-adt/auth-stores\r\n```\r\n\r\n## Overview\r\n\r\nThis package implements the `IServiceKeyStore` and `ISessionStore` interfaces from `@mcp-abap-adt/interfaces`:\r\n\r\n- **Service Key Stores**: Read service key JSON files from a specified directory\r\n- **Session Stores**: Read/write session data from/to `.env` files or in-memory storage\r\n- **File Handlers**: Utility classes for working with JSON and ENV files\r\n\r\n## Responsibilities and Design Principles\r\n\r\n### Core Development Principle\r\n\r\n**Interface-Only Communication**: This package follows a fundamental development principle: **all interactions with external dependencies happen ONLY through interfaces**. The code knows **NOTHING beyond what is defined in the interfaces**.\r\n\r\nThis means:\r\n- Does not know about concrete implementation classes from other packages\r\n- Does not know about internal data structures or methods not defined in interfaces\r\n- Does not make assumptions about implementation behavior beyond interface contracts\r\n- Does not access properties or methods not explicitly defined in interfaces\r\n\r\nThis principle ensures:\r\n- **Loose coupling**: Stores are decoupled from concrete implementations in other packages\r\n- **Flexibility**: New implementations can be added without modifying stores\r\n- **Testability**: Easy to mock dependencies for testing\r\n- **Maintainability**: Changes to implementations don't affect stores\r\n\r\n### Package Responsibilities\r\n\r\nThis package is responsible for:\r\n\r\n1. **Implementing storage interfaces**: Provides concrete implementations of `IServiceKeyStore` and `ISessionStore` interfaces defined in `@mcp-abap-adt/interfaces`\r\n2. **File I/O operations**: Handles reading and writing service key JSON files and session `.env` files\r\n3. **Data format conversion**: Converts between interface types (`IConfig`, `IConnectionConfig`, `IAuthorizationConfig`) and internal storage formats\r\n4. **Platform-specific handling**: Provides different store implementations for ABAP, BTP, and XSUAA with their specific data formats\r\n\r\n#### What This Package Does\r\n\r\n- **Implements interfaces**: Provides concrete implementations of `IServiceKeyStore` and `ISessionStore`\r\n- **Handles file operations**: Reads/writes JSON and `.env` files using atomic operations\r\n- **Manages data formats**: Converts between interface types and internal storage formats (e.g., `AbapSessionData`, `BtpBaseSessionData`)\r\n- **Provides utilities**: File handlers (`JsonFileHandler`, `EnvFileHandler`) for safe file operations\r\n\r\n#### What This Package Does NOT Do\r\n\r\n- **Does NOT implement authentication logic**: Token acquisition and OAuth2 flows are handled by `@mcp-abap-adt/auth-providers`\r\n- **Does NOT orchestrate authentication**: Token lifecycle management is handled by `@mcp-abap-adt/auth-broker`\r\n- **Does NOT know about token validation**: Token validation logic is not part of this package\r\n- **Does NOT interact with external services**: All HTTP requests and OAuth flows are handled by other packages\r\n\r\n### External Dependencies\r\n\r\nThis package interacts with external packages **ONLY through interfaces**:\r\n\r\n- **`@mcp-abap-adt/interfaces`**: Uses interfaces (`IServiceKeyStore`, `ISessionStore`, `IConfig`, `IConnectionConfig`, `IAuthorizationConfig`, `ILogger`) - does not know about concrete implementations in other packages\r\n- **No direct dependencies on other packages**: All interactions happen through well-defined interfaces\r\n\r\n## Store Types\r\n\r\n### Service Key Stores\r\n\r\nService key stores read JSON files containing UAA credentials and connection information:\r\n\r\n- **`BtpServiceKeyStore`** - Reads XSUAA service keys for base BTP (direct XSUAA format)\r\n- **`AbapServiceKeyStore`** - Reads ABAP service keys (with nested `uaa` object)\r\n- **`XsuaaServiceKeyStore`** - Reads XSUAA service keys (alias for BtpServiceKeyStore)\r\n\r\n### Session Stores\r\n\r\nSession stores manage authentication tokens and configuration:\r\n\r\n**File-based stores** (persist to `.env` files):\r\n- **`BtpSessionStore`** - Stores base BTP sessions using `XSUAA_*` environment variables\r\n- **`AbapSessionStore`** - Stores ABAP sessions using `SAP_*` environment variables\r\n- **`XsuaaSessionStore`** - Stores XSUAA sessions using `XSUAA_*` environment variables\r\n\r\n**In-memory stores** (non-persistent, secure):\r\n- **`SafeBtpSessionStore`** - In-memory store for base BTP sessions\r\n- **`SafeAbapSessionStore`** - In-memory store for ABAP sessions\r\n- **`SafeXsuaaSessionStore`** - In-memory store for XSUAA sessions\r\n\r\n**File-based single-file stores**:\r\n- **`EnvFileSessionStore`** - Reads from a specific `.env` file path (e.g., `--env /path/to/.env`)\r\n\r\n## Usage\r\n\r\n### BTP Stores (base BTP without sapUrl)\r\n\r\n```typescript\r\nimport { BtpServiceKeyStore, BtpSessionStore, SafeBtpSessionStore } from '@mcp-abap-adt/auth-stores';\r\n\r\n// Service key store - reads {destination}.json files from directory\r\nconst serviceKeyStore = new BtpServiceKeyStore('/path/to/service-keys');\r\n\r\n// File-based session store - reads/writes {destination}.env files\r\n// defaultServiceUrl is REQUIRED (cannot be obtained from service key)\r\nconst sessionStore = new BtpSessionStore('/path/to/sessions', 'https://default.mcp.com', logger);\r\n\r\n// In-memory session store (non-persistent)\r\n// defaultServiceUrl is REQUIRED (cannot be obtained from service key)\r\nconst safeSessionStore = new SafeBtpSessionStore('https://default.mcp.com', logger);\r\n```\r\n\r\n### ABAP Stores (with sapUrl)\r\n\r\n```typescript\r\nimport {\r\n  AbapServiceKeyStore,\r\n  AbapSessionStore,\r\n  SafeAbapSessionStore,\r\n  SamlSessionStore,\r\n  SafeSamlSessionStore,\r\n} from '@mcp-abap-adt/auth-stores';\r\n\r\n// Service key store - reads ABAP service keys with nested uaa object\r\nconst serviceKeyStore = new AbapServiceKeyStore('/path/to/service-keys');\r\n\r\n// File-based session store - stores ABAP sessions with SAP_* env vars\r\nconst sessionStore = new AbapSessionStore('/path/to/sessions');\r\n\r\n// In-memory session store\r\nconst safeSessionStore = new SafeAbapSessionStore();\r\n\r\n// SAML aliases (same behavior as ABAP stores)\r\nconst samlSessionStore = new SamlSessionStore('/path/to/sessions');\r\nconst safeSamlSessionStore = new SafeSamlSessionStore();\r\n```\r\n\r\n### XSUAA Stores\r\n\r\n```typescript\r\nimport { XsuaaServiceKeyStore, XsuaaSessionStore, SafeXsuaaSessionStore } from '@mcp-abap-adt/auth-stores';\r\n\r\n// Service key store - reads XSUAA service keys\r\nconst serviceKeyStore = new XsuaaServiceKeyStore('/path/to/service-keys');\r\n\r\n// File-based session store - stores XSUAA sessions\r\n// defaultServiceUrl is REQUIRED (cannot be obtained from service key)\r\nconst sessionStore = new XsuaaSessionStore('/path/to/sessions', 'https://default.mcp.com', logger);\r\n\r\n// In-memory session store\r\n// defaultServiceUrl is REQUIRED (cannot be obtained from service key)\r\nconst safeSessionStore = new SafeXsuaaSessionStore('https://default.mcp.com', logger);\r\n```\r\n\r\n### EnvFileSessionStore (Single File)\r\n\r\n`EnvFileSessionStore` reads connection configuration from a specific `.env` file path rather than a directory. This is useful for the `--env` CLI option.\r\n\r\n```typescript\r\nimport { EnvFileSessionStore } from '@mcp-abap-adt/auth-stores';\r\n\r\n// Create store pointing to specific .env file\r\nconst store = new EnvFileSessionStore('/path/to/.env', logger);\r\n\r\n// Check the auth type from the file\r\nconst authType = store.getAuthType(); // 'basic' | 'jwt' | 'saml' | null\r\n\r\n// Load session (works like other session stores)\r\nconst config = await store.loadSession('default');\r\nconsole.log(config?.serviceUrl, config?.authType);\r\n\r\n// For basic auth\r\nconsole.log(config?.username, config?.password);\r\n\r\n// For JWT auth\r\nconsole.log(config?.authorizationToken, config?.refreshToken);\r\n```\r\n\r\n**Env file format:**\r\n```bash\r\n# Connection\r\nSAP_URL=https://your-sap-system.com\r\nSAP_CLIENT=100\r\n\r\n# Auth type: 'basic', 'jwt', or 'saml' (defaults to 'basic')\r\nSAP_AUTH_TYPE=basic\r\n\r\n# Basic auth credentials\r\nSAP_USERNAME=your-username\r\nSAP_PASSWORD=your-password\r\n\r\n# OR JWT auth\r\n# SAP_AUTH_TYPE=jwt\r\n# SAP_JWT_TOKEN=your-jwt-token\r\n# SAP_REFRESH_TOKEN=your-refresh-token\r\n# SAP_UAA_URL=https://uaa.example.com\r\n# SAP_UAA_CLIENT_ID=client-id\r\n# SAP_UAA_CLIENT_SECRET=client-secret\r\n\r\n# OR SAML auth (session cookies, base64-encoded)\r\n# SAP_AUTH_TYPE=saml\r\n# SAP_SESSION_COOKIES_B64=base64-encoded-cookie-string\r\n```\r\n\r\n**Important**: This store is **read-only** for the file. Token updates (e.g., refreshed JWT tokens) are stored in memory only and do not modify the original `.env` file.\r\n\r\n### Directory Configuration\r\n\r\nAll stores accept a single directory path in the constructor:\r\n\r\n```typescript\r\n// Single directory path\r\nconst store = new BtpServiceKeyStore('/path/to/service-keys');\r\n\r\n// File-based session stores automatically create directory in constructor if it doesn't exist\r\nconst sessionStore = new AbapSessionStore('/path/to/sessions'); // Directory created automatically\r\n```\r\n\r\n**Note**: File-based session stores (`AbapSessionStore`, `BtpSessionStore`, `XsuaaSessionStore`) automatically create the directory in the constructor if it doesn't exist. Stores are ready to use immediately after construction.\r\n\r\n### Default Service URL Configuration\r\n\r\n**For XSUAA and BTP stores**: `defaultServiceUrl` is **required** in the constructor because `serviceUrl` cannot be obtained from service keys:\r\n- `XsuaaSessionStore(directory, defaultServiceUrl, log?)` - `defaultServiceUrl` is required\r\n- `SafeXsuaaSessionStore(defaultServiceUrl, log?)` - `defaultServiceUrl` is required\r\n- `BtpSessionStore(directory, defaultServiceUrl, log?)` - `defaultServiceUrl` is required\r\n- `SafeBtpSessionStore(defaultServiceUrl, log?)` - `defaultServiceUrl` is required\r\n\r\n**For ABAP stores**: `defaultServiceUrl` is **optional** because `serviceUrl` can be obtained from ABAP service keys:\r\n- `AbapSessionStore(directory, log?, defaultServiceUrl?)` - `defaultServiceUrl` is optional\r\n- `SafeAbapSessionStore(log?, defaultServiceUrl?)` - `defaultServiceUrl` is optional\r\n\r\nThe `defaultServiceUrl` is used when creating new sessions via `setConnectionConfig` or `setAuthorizationConfig` if `config.serviceUrl` is not provided. It is never used to modify existing sessions.\r\n\r\n### Service Key Format\r\n\r\n**ABAP Service Key** (with nested `uaa` object):\r\n```json\r\n{\r\n  \"uaa\": {\r\n    \"url\": \"https://...authentication...hana.ondemand.com\",\r\n    \"clientid\": \"...\",\r\n    \"clientsecret\": \"...\"\r\n  },\r\n  \"abap\": {\r\n    \"url\": \"https://...abap...hana.ondemand.com\",\r\n    \"client\": \"001\"\r\n  }\r\n}\r\n```\r\n\r\n**XSUAA Service Key** (direct format):\r\n```json\r\n{\r\n  \"url\": \"https://...authentication...hana.ondemand.com\",\r\n  \"clientid\": \"...\",\r\n  \"clientsecret\": \"...\",\r\n  \"apiurl\": \"https://...api...hana.ondemand.com\"\r\n}\r\n```\r\n\r\n## File Handlers\r\n\r\nThis package provides utility classes for safe file operations:\r\n\r\n### Error Handling\r\n\r\nAll service key stores throw typed errors for better error handling:\r\n\r\n```typescript\r\nimport { \r\n  BtpServiceKeyStore,\r\n  FileNotFoundError,\r\n  ParseError,\r\n  InvalidConfigError \r\n} from '@mcp-abap-adt/auth-stores';\r\nimport { STORE_ERROR_CODES } from '@mcp-abap-adt/interfaces';\r\n\r\nconst serviceKeyStore = new BtpServiceKeyStore('/path/to/keys');\r\n\r\ntry {\r\n  const authConfig = await serviceKeyStore.getAuthorizationConfig('TRIAL');\r\n  console.log('Auth config loaded:', authConfig);\r\n} catch (error: any) {\r\n  if (error.code === STORE_ERROR_CODES.FILE_NOT_FOUND) {\r\n    // File not found - returns null instead of throwing\r\n    console.error('Service key file not found:', error.filePath);\r\n  } else if (error.code === STORE_ERROR_CODES.PARSE_ERROR) {\r\n    // JSON parsing failed or invalid format\r\n    console.error('Failed to parse service key:', error.filePath);\r\n    console.error('Cause:', error.cause);\r\n  } else if (error.code === STORE_ERROR_CODES.INVALID_CONFIG) {\r\n    // Required UAA fields missing - returns null instead of throwing\r\n    console.error('Invalid config:', error.missingFields);\r\n  } else if (error.code === STORE_ERROR_CODES.STORAGE_ERROR) {\r\n    // File write/permission error\r\n    console.error('Storage operation failed:', error.operation);\r\n    console.error('Cause:', error.cause);\r\n  } else {\r\n    // Generic error\r\n    console.error('Unexpected error:', error.message);\r\n  }\r\n}\r\n```\r\n\r\n**Error Types:**\r\n- **`FileNotFoundError`** - Service key file not found (includes `filePath`)\r\n- **`ParseError`** - JSON parsing failed or invalid format (includes `filePath` and `cause`)\r\n- **`InvalidConfigError`** - Required configuration fields missing (includes `missingFields` array)\r\n- **`StorageError`** - File write or permission error (includes `operation` and `cause`)\r\n\r\n**Note**: Most errors result in `null` return values rather than exceptions. Only fatal errors (like JSON parsing failures) throw exceptions.\r\n\r\n## File Handlers\r\n\r\nUtility classes for working with files:\r\n\r\n### JsonFileHandler\r\n\r\n```typescript\r\nimport { JsonFileHandler } from '@mcp-abap-adt/auth-stores';\r\n\r\n// Load JSON file\r\nconst data = await JsonFileHandler.load('TRIAL.json', '/path/to/directory');\r\n\r\n// Save JSON file (atomic write)\r\nawait JsonFileHandler.save('/path/to/file.json', { key: 'value' });\r\n```\r\n\r\n### EnvFileHandler\r\n\r\n```typescript\r\nimport { EnvFileHandler } from '@mcp-abap-adt/auth-stores';\r\n\r\n// Load .env file\r\nconst vars = await EnvFileHandler.load('TRIAL.env', '/path/to/directory');\r\n\r\n// Save .env file (atomic write, preserves existing variables)\r\nawait EnvFileHandler.save('/path/to/file.env', {\r\n  KEY1: 'value1',\r\n  KEY2: 'value2'\r\n}, true); // preserveExisting = true\r\n```\r\n\r\n## Utilities\r\n\r\n### Constants\r\n\r\n```typescript\r\nimport {\r\n  ABAP_AUTHORIZATION_VARS,\r\n  ABAP_CONNECTION_VARS,\r\n  BTP_AUTHORIZATION_VARS,\r\n  BTP_CONNECTION_VARS,\r\n  XSUAA_AUTHORIZATION_VARS,\r\n  XSUAA_CONNECTION_VARS\r\n} from '@mcp-abap-adt/auth-stores';\r\n```\r\n\r\n### Service Key Loaders\r\n\r\n```typescript\r\nimport { loadServiceKey, loadXSUAAServiceKey } from '@mcp-abap-adt/auth-stores';\r\n\r\n// Load ABAP service key (auto-detects format)\r\nconst abapKey = await loadServiceKey('TRIAL', '/path/to/service-keys');\r\n\r\n// Load XSUAA service key\r\nconst xsuaaKey = await loadXSUAAServiceKey('mcp', '/path/to/service-keys');\r\n```\r\n\r\n## Debug Logging\r\n\r\nStores support optional logging through the `ILogger` interface. To enable detailed logging:\r\n\r\n### Using Logger in Code\r\n\r\n```typescript\r\nimport { AbapServiceKeyStore } from '@mcp-abap-adt/auth-stores';\r\nimport type { ILogger } from '@mcp-abap-adt/interfaces';\r\n\r\n// Create logger (or use your own implementation)\r\nconst logger: ILogger = {\r\n  debug: (msg) => console.debug(msg),\r\n  info: (msg) => console.info(msg),\r\n  warn: (msg) => console.warn(msg),\r\n  error: (msg) => console.error(msg),\r\n};\r\n\r\n// Pass logger to store constructor\r\nconst store = new AbapServiceKeyStore('/path/to/service-keys', logger);\r\nconst sessionStore = new AbapSessionStore('/path/to/sessions', logger);\r\n```\r\n\r\n### Using Test Logger in Tests\r\n\r\nFor tests, use the `createTestLogger` helper which respects environment variables:\r\n\r\n```typescript\r\nimport { createTestLogger } from './__tests__/helpers/testLogger';\r\n\r\n// Logger will output only if DEBUG_AUTH_STORES=true is set\r\nconst logger = createTestLogger('MY-TEST');\r\nconst store = new AbapServiceKeyStore('/path/to/service-keys', logger);\r\n```\r\n\r\n### Environment Variables\r\n\r\nTo enable logging in tests or when using `createTestLogger`:\r\n\r\n```bash\r\n# Enable logging for auth stores (short name)\r\nDEBUG_STORES=true npm test\r\n\r\n# Or use long name (backward compatibility)\r\nDEBUG_AUTH_STORES=true npm test\r\n\r\n# Or enable via general DEBUG variable\r\nDEBUG=true npm test\r\n\r\n# Or include in DEBUG list\r\nDEBUG=stores npm test\r\n# Or\r\nDEBUG=auth-stores npm test\r\n\r\n# Set log level (debug, info, warn, error)\r\nLOG_LEVEL=debug npm test\r\n```\r\n\r\n**Note**: Logging requires explicit enable via environment variables. Both `DEBUG_STORES` (short) and `DEBUG_AUTH_STORES` (long) are supported for backward compatibility.\r\n\r\nLogging shows:\r\n- **File operations**: Which files are read/written, file sizes, file paths\r\n- **Parsing operations**: Structure of parsed data, validation results, keys found\r\n- **Storage operations**: What data is saved/loaded, token lengths, refresh token presence, URLs\r\n- **Token formatting**: Tokens are logged in truncated format (start...end) for security and readability\r\n- **Errors**: Detailed error information with context\r\n\r\n**Logging Features**:\r\n- **Token Formatting**: Tokens are logged in truncated format (start...end) for security\r\n- **Structured Logging**: Uses `DefaultLogger` from `@mcp-abap-adt/logger` for proper formatting with icons and level prefixes\r\n- **Log Levels**: Controlled via `LOG_LEVEL` or `AUTH_LOG_LEVEL` environment variable (error, warn, info, debug)\r\n\r\nExample output with `DEBUG_STORES=true LOG_LEVEL=debug`:\r\n```\r\n[INFO] ℹ️ [TEST-STORE] Reading service key file: /path/to/TRIAL.json\r\n[DEBUG] 🐛 [TEST-STORE] File read successfully, size: 121 bytes, keys: uaa\r\n[DEBUG] 🐛 [TEST-STORE] Parsed service key structure: hasUaa(true), uaaKeys(url, clientid, clientsecret)\r\n[INFO] ℹ️ [TEST-STORE] Authorization config loaded from /path/to/TRIAL.json: uaaUrl(https://...authentication...), clientId(test-client...)\r\n[DEBUG] 🐛 [TEST-STORE] Reading env file: /path/to/TRIAL.env\r\n[DEBUG] 🐛 [TEST-STORE] Env file read successfully, size: 245 bytes\r\n[INFO] ℹ️ [TEST-STORE] Session loaded for TRIAL: token(2263 chars, eyJ0eXAiOiJKV1QiLCJqaWQiO...Q5ti7aYmEzItIDuLp7axNYo6w), refreshToken(fcc971e1cf1548629216a96b0680eb85-r), sapUrl(https://...abap...)\r\n```\r\n\r\n**Note**: Logging only works when a logger is explicitly provided. Stores will not output anything to console if no logger is passed.\r\n\r\n## Testing\r\n\r\nThe package includes both unit tests (with mocked file system) and integration tests (with real files).\r\n\r\n### Unit Tests\r\n\r\nUnit tests use Jest with mocked file system operations:\r\n\r\n```bash\r\nnpm test\r\n```\r\n\r\n### Integration Tests\r\n\r\nIntegration tests work with real files from `tests/test-config.yaml`:\r\n\r\n1. Copy `tests/test-config.yaml.template` to `tests/test-config.yaml`\r\n2. Fill in real paths and destinations\r\n3. Run tests - integration tests will use real files if configured\r\n\r\n```yaml\r\nauth_broker:\r\n  paths:\r\n    service_keys_dir: ~/.config/mcp-abap-adt/service-keys/\r\n    sessions_dir: ~/.config/mcp-abap-adt/sessions/\r\n  abap:\r\n    destination: \"TRIAL\"\r\n  xsuaa:\r\n    btp_destination: \"mcp\"\r\n    mcp_url: \"https://...\"\r\n```\r\n\r\nIntegration tests will skip if `test-config.yaml` is not configured or contains placeholder values.\r\n\r\n## Architecture\r\n\r\n### File Operations\r\n\r\n- **Service Key Stores** use `JsonFileHandler` to read JSON files\r\n- **Session Stores** use `EnvFileHandler` to read/write `.env` files\r\n- All file writes are atomic (write to temp file, then rename)\r\n\r\n### Store Implementation\r\n\r\n- All stores implement `IServiceKeyStore` or `ISessionStore` interfaces from `@mcp-abap-adt/interfaces`\r\n- Stores accept a single directory path in constructor\r\n- File-based session stores automatically create directories in constructor if they don't exist\r\n- Session stores automatically create sessions when calling `setConnectionConfig` or `setAuthorizationConfig` (no need to call `saveSession` first)\r\n- In-memory stores (`Safe*SessionStore`) don't persist data to disk\r\n\r\n### Session Store Behavior\r\n\r\nSession stores are designed to work seamlessly with `AuthBroker`:\r\n\r\n- **Ready after construction**: File-based stores create directory automatically, stores are ready to use immediately\r\n- **Automatic session creation**: Calling `setConnectionConfig` or `setAuthorizationConfig` on an empty store creates a new session\r\n- **ABAP stores**: Require `serviceUrl` when creating new session (from config or `defaultServiceUrl` parameter)\r\n- **BTP/XSUAA stores**: Require `defaultServiceUrl` in constructor (cannot be obtained from service key), used when creating new sessions if `config.serviceUrl` is not provided\r\n- **Token updates**: `setConnectionConfig` updates token if provided, preserves existing token if not provided\r\n- **Session updates**: When updating existing sessions, only `config.serviceUrl` is used if explicitly provided; `defaultServiceUrl` is never used to modify existing sessions\r\n\r\n## Dependencies\r\n\r\n- `@mcp-abap-adt/interfaces` (^0.1.4) - Interface definitions (`IServiceKeyStore`, `ISessionStore`, `IConfig`, `IConnectionConfig`, `IAuthorizationConfig`, `ILogger`)\r\n- `dotenv` - Environment variable parsing\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md","_rev":"1-6bf048c7116d7d589b6104866346fbd0"}