npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcp-abap-adt/auth-stores

v1.0.4

Published

Stores for MCP ABAP ADT auth-broker - BTP, ABAP, and XSUAA implementations

Readme

@mcp-abap-adt/auth-stores

Stores for MCP ABAP ADT auth-broker - BTP, ABAP, and XSUAA implementations.

This package provides file-based and in-memory stores for service keys and sessions used by the @mcp-abap-adt/auth-broker package.

Installation

npm install @mcp-abap-adt/auth-stores

Overview

This package implements the IServiceKeyStore and ISessionStore interfaces from @mcp-abap-adt/interfaces:

  • Service Key Stores: Read service key JSON files from a specified directory
  • Session Stores: Read/write session data from/to .env files or in-memory storage
  • File Handlers: Utility classes for working with JSON and ENV files

Responsibilities and Design Principles

Core Development Principle

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.

This means:

  • Does not know about concrete implementation classes from other packages
  • Does not know about internal data structures or methods not defined in interfaces
  • Does not make assumptions about implementation behavior beyond interface contracts
  • Does not access properties or methods not explicitly defined in interfaces

This principle ensures:

  • Loose coupling: Stores are decoupled from concrete implementations in other packages
  • Flexibility: New implementations can be added without modifying stores
  • Testability: Easy to mock dependencies for testing
  • Maintainability: Changes to implementations don't affect stores

Package Responsibilities

This package is responsible for:

  1. Implementing storage interfaces: Provides concrete implementations of IServiceKeyStore and ISessionStore interfaces defined in @mcp-abap-adt/interfaces
  2. File I/O operations: Handles reading and writing service key JSON files and session .env files
  3. Data format conversion: Converts between interface types (IConfig, IConnectionConfig, IAuthorizationConfig) and internal storage formats
  4. Platform-specific handling: Provides different store implementations for ABAP, BTP, and XSUAA with their specific data formats

What This Package Does

  • Implements interfaces: Provides concrete implementations of IServiceKeyStore and ISessionStore
  • Handles file operations: Reads/writes JSON and .env files using atomic operations
  • Manages data formats: Converts between interface types and internal storage formats (e.g., AbapSessionData, BtpBaseSessionData)
  • Provides utilities: File handlers (JsonFileHandler, EnvFileHandler) for safe file operations

What This Package Does NOT Do

  • Does NOT implement authentication logic: Token acquisition and OAuth2 flows are handled by @mcp-abap-adt/auth-providers
  • Does NOT orchestrate authentication: Token lifecycle management is handled by @mcp-abap-adt/auth-broker
  • Does NOT know about token validation: Token validation logic is not part of this package
  • Does NOT interact with external services: All HTTP requests and OAuth flows are handled by other packages

External Dependencies

This package interacts with external packages ONLY through interfaces:

  • @mcp-abap-adt/interfaces: Uses interfaces (IServiceKeyStore, ISessionStore, IConfig, IConnectionConfig, IAuthorizationConfig, ILogger) - does not know about concrete implementations in other packages
  • No direct dependencies on other packages: All interactions happen through well-defined interfaces

Store Types

Service Key Stores

Service key stores read JSON files containing UAA credentials and connection information:

  • BtpServiceKeyStore - Reads XSUAA service keys for base BTP (direct XSUAA format)
  • AbapServiceKeyStore - Reads ABAP service keys (with nested uaa object)
  • XsuaaServiceKeyStore - Reads XSUAA service keys (alias for BtpServiceKeyStore)

Session Stores

Session stores manage authentication tokens and configuration:

File-based stores (persist to .env files):

  • BtpSessionStore - Stores base BTP sessions using XSUAA_* environment variables
  • AbapSessionStore - Stores ABAP sessions using SAP_* environment variables
  • XsuaaSessionStore - Stores XSUAA sessions using XSUAA_* environment variables

In-memory stores (non-persistent, secure):

  • SafeBtpSessionStore - In-memory store for base BTP sessions
  • SafeAbapSessionStore - In-memory store for ABAP sessions
  • SafeXsuaaSessionStore - In-memory store for XSUAA sessions

File-based single-file stores:

  • EnvFileSessionStore - Reads from a specific .env file path (e.g., --env /path/to/.env)

Usage

BTP Stores (base BTP without sapUrl)

import { BtpServiceKeyStore, BtpSessionStore, SafeBtpSessionStore } from '@mcp-abap-adt/auth-stores';

// Service key store - reads {destination}.json files from directory
const serviceKeyStore = new BtpServiceKeyStore('/path/to/service-keys');

// File-based session store - reads/writes {destination}.env files
// defaultServiceUrl is REQUIRED (cannot be obtained from service key)
const sessionStore = new BtpSessionStore('/path/to/sessions', 'https://default.mcp.com', logger);

// In-memory session store (non-persistent)
// defaultServiceUrl is REQUIRED (cannot be obtained from service key)
const safeSessionStore = new SafeBtpSessionStore('https://default.mcp.com', logger);

ABAP Stores (with sapUrl)

import {
  AbapServiceKeyStore,
  AbapSessionStore,
  SafeAbapSessionStore,
  SamlSessionStore,
  SafeSamlSessionStore,
} from '@mcp-abap-adt/auth-stores';

// Service key store - reads ABAP service keys with nested uaa object
const serviceKeyStore = new AbapServiceKeyStore('/path/to/service-keys');

// File-based session store - stores ABAP sessions with SAP_* env vars
const sessionStore = new AbapSessionStore('/path/to/sessions');

// In-memory session store
const safeSessionStore = new SafeAbapSessionStore();

// SAML aliases (same behavior as ABAP stores)
const samlSessionStore = new SamlSessionStore('/path/to/sessions');
const safeSamlSessionStore = new SafeSamlSessionStore();

XSUAA Stores

import { XsuaaServiceKeyStore, XsuaaSessionStore, SafeXsuaaSessionStore } from '@mcp-abap-adt/auth-stores';

// Service key store - reads XSUAA service keys
const serviceKeyStore = new XsuaaServiceKeyStore('/path/to/service-keys');

// File-based session store - stores XSUAA sessions
// defaultServiceUrl is REQUIRED (cannot be obtained from service key)
const sessionStore = new XsuaaSessionStore('/path/to/sessions', 'https://default.mcp.com', logger);

// In-memory session store
// defaultServiceUrl is REQUIRED (cannot be obtained from service key)
const safeSessionStore = new SafeXsuaaSessionStore('https://default.mcp.com', logger);

EnvFileSessionStore (Single File)

EnvFileSessionStore reads connection configuration from a specific .env file path rather than a directory. This is useful for the --env CLI option.

import { EnvFileSessionStore } from '@mcp-abap-adt/auth-stores';

// Create store pointing to specific .env file
const store = new EnvFileSessionStore('/path/to/.env', logger);

// Check the auth type from the file
const authType = store.getAuthType(); // 'basic' | 'jwt' | 'saml' | null

// Load session (works like other session stores)
const config = await store.loadSession('default');
console.log(config?.serviceUrl, config?.authType);

// For basic auth
console.log(config?.username, config?.password);

// For JWT auth
console.log(config?.authorizationToken, config?.refreshToken);

Env file format:

# Connection
SAP_URL=https://your-sap-system.com
SAP_CLIENT=100

# Auth type: 'basic', 'jwt', or 'saml' (defaults to 'basic')
SAP_AUTH_TYPE=basic

# Basic auth credentials
SAP_USERNAME=your-username
SAP_PASSWORD=your-password

# OR JWT auth
# SAP_AUTH_TYPE=jwt
# SAP_JWT_TOKEN=your-jwt-token
# SAP_REFRESH_TOKEN=your-refresh-token
# SAP_UAA_URL=https://uaa.example.com
# SAP_UAA_CLIENT_ID=client-id
# SAP_UAA_CLIENT_SECRET=client-secret

# OR SAML auth (session cookies, base64-encoded)
# SAP_AUTH_TYPE=saml
# SAP_SESSION_COOKIES_B64=base64-encoded-cookie-string

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.

Directory Configuration

All stores accept a single directory path in the constructor:

// Single directory path
const store = new BtpServiceKeyStore('/path/to/service-keys');

// File-based session stores automatically create directory in constructor if it doesn't exist
const sessionStore = new AbapSessionStore('/path/to/sessions'); // Directory created automatically

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.

Default Service URL Configuration

For XSUAA and BTP stores: defaultServiceUrl is required in the constructor because serviceUrl cannot be obtained from service keys:

  • XsuaaSessionStore(directory, defaultServiceUrl, log?) - defaultServiceUrl is required
  • SafeXsuaaSessionStore(defaultServiceUrl, log?) - defaultServiceUrl is required
  • BtpSessionStore(directory, defaultServiceUrl, log?) - defaultServiceUrl is required
  • SafeBtpSessionStore(defaultServiceUrl, log?) - defaultServiceUrl is required

For ABAP stores: defaultServiceUrl is optional because serviceUrl can be obtained from ABAP service keys:

  • AbapSessionStore(directory, log?, defaultServiceUrl?) - defaultServiceUrl is optional
  • SafeAbapSessionStore(log?, defaultServiceUrl?) - defaultServiceUrl is optional

The 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.

Service Key Format

ABAP Service Key (with nested uaa object):

{
  "uaa": {
    "url": "https://...authentication...hana.ondemand.com",
    "clientid": "...",
    "clientsecret": "..."
  },
  "abap": {
    "url": "https://...abap...hana.ondemand.com",
    "client": "001"
  }
}

XSUAA Service Key (direct format):

{
  "url": "https://...authentication...hana.ondemand.com",
  "clientid": "...",
  "clientsecret": "...",
  "apiurl": "https://...api...hana.ondemand.com"
}

File Handlers

This package provides utility classes for safe file operations:

Error Handling

All service key stores throw typed errors for better error handling:

import { 
  BtpServiceKeyStore,
  FileNotFoundError,
  ParseError,
  InvalidConfigError 
} from '@mcp-abap-adt/auth-stores';
import { STORE_ERROR_CODES } from '@mcp-abap-adt/interfaces';

const serviceKeyStore = new BtpServiceKeyStore('/path/to/keys');

try {
  const authConfig = await serviceKeyStore.getAuthorizationConfig('TRIAL');
  console.log('Auth config loaded:', authConfig);
} catch (error: any) {
  if (error.code === STORE_ERROR_CODES.FILE_NOT_FOUND) {
    // File not found - returns null instead of throwing
    console.error('Service key file not found:', error.filePath);
  } else if (error.code === STORE_ERROR_CODES.PARSE_ERROR) {
    // JSON parsing failed or invalid format
    console.error('Failed to parse service key:', error.filePath);
    console.error('Cause:', error.cause);
  } else if (error.code === STORE_ERROR_CODES.INVALID_CONFIG) {
    // Required UAA fields missing - returns null instead of throwing
    console.error('Invalid config:', error.missingFields);
  } else if (error.code === STORE_ERROR_CODES.STORAGE_ERROR) {
    // File write/permission error
    console.error('Storage operation failed:', error.operation);
    console.error('Cause:', error.cause);
  } else {
    // Generic error
    console.error('Unexpected error:', error.message);
  }
}

Error Types:

  • FileNotFoundError - Service key file not found (includes filePath)
  • ParseError - JSON parsing failed or invalid format (includes filePath and cause)
  • InvalidConfigError - Required configuration fields missing (includes missingFields array)
  • StorageError - File write or permission error (includes operation and cause)

Note: Most errors result in null return values rather than exceptions. Only fatal errors (like JSON parsing failures) throw exceptions.

File Handlers

Utility classes for working with files:

JsonFileHandler

import { JsonFileHandler } from '@mcp-abap-adt/auth-stores';

// Load JSON file
const data = await JsonFileHandler.load('TRIAL.json', '/path/to/directory');

// Save JSON file (atomic write)
await JsonFileHandler.save('/path/to/file.json', { key: 'value' });

EnvFileHandler

import { EnvFileHandler } from '@mcp-abap-adt/auth-stores';

// Load .env file
const vars = await EnvFileHandler.load('TRIAL.env', '/path/to/directory');

// Save .env file (atomic write, preserves existing variables)
await EnvFileHandler.save('/path/to/file.env', {
  KEY1: 'value1',
  KEY2: 'value2'
}, true); // preserveExisting = true

Utilities

Constants

import {
  ABAP_AUTHORIZATION_VARS,
  ABAP_CONNECTION_VARS,
  BTP_AUTHORIZATION_VARS,
  BTP_CONNECTION_VARS,
  XSUAA_AUTHORIZATION_VARS,
  XSUAA_CONNECTION_VARS
} from '@mcp-abap-adt/auth-stores';

Service Key Loaders

import { loadServiceKey, loadXSUAAServiceKey } from '@mcp-abap-adt/auth-stores';

// Load ABAP service key (auto-detects format)
const abapKey = await loadServiceKey('TRIAL', '/path/to/service-keys');

// Load XSUAA service key
const xsuaaKey = await loadXSUAAServiceKey('mcp', '/path/to/service-keys');

Debug Logging

Stores support optional logging through the ILogger interface. To enable detailed logging:

Using Logger in Code

import { AbapServiceKeyStore } from '@mcp-abap-adt/auth-stores';
import type { ILogger } from '@mcp-abap-adt/interfaces';

// Create logger (or use your own implementation)
const logger: ILogger = {
  debug: (msg) => console.debug(msg),
  info: (msg) => console.info(msg),
  warn: (msg) => console.warn(msg),
  error: (msg) => console.error(msg),
};

// Pass logger to store constructor
const store = new AbapServiceKeyStore('/path/to/service-keys', logger);
const sessionStore = new AbapSessionStore('/path/to/sessions', logger);

Using Test Logger in Tests

For tests, use the createTestLogger helper which respects environment variables:

import { createTestLogger } from './__tests__/helpers/testLogger';

// Logger will output only if DEBUG_AUTH_STORES=true is set
const logger = createTestLogger('MY-TEST');
const store = new AbapServiceKeyStore('/path/to/service-keys', logger);

Environment Variables

To enable logging in tests or when using createTestLogger:

# Enable logging for auth stores (short name)
DEBUG_STORES=true npm test

# Or use long name (backward compatibility)
DEBUG_AUTH_STORES=true npm test

# Or enable via general DEBUG variable
DEBUG=true npm test

# Or include in DEBUG list
DEBUG=stores npm test
# Or
DEBUG=auth-stores npm test

# Set log level (debug, info, warn, error)
LOG_LEVEL=debug npm test

Note: Logging requires explicit enable via environment variables. Both DEBUG_STORES (short) and DEBUG_AUTH_STORES (long) are supported for backward compatibility.

Logging shows:

  • File operations: Which files are read/written, file sizes, file paths
  • Parsing operations: Structure of parsed data, validation results, keys found
  • Storage operations: What data is saved/loaded, token lengths, refresh token presence, URLs
  • Token formatting: Tokens are logged in truncated format (start...end) for security and readability
  • Errors: Detailed error information with context

Logging Features:

  • Token Formatting: Tokens are logged in truncated format (start...end) for security
  • Structured Logging: Uses DefaultLogger from @mcp-abap-adt/logger for proper formatting with icons and level prefixes
  • Log Levels: Controlled via LOG_LEVEL or AUTH_LOG_LEVEL environment variable (error, warn, info, debug)

Example output with DEBUG_STORES=true LOG_LEVEL=debug:

[INFO] ℹ️ [TEST-STORE] Reading service key file: /path/to/TRIAL.json
[DEBUG] 🐛 [TEST-STORE] File read successfully, size: 121 bytes, keys: uaa
[DEBUG] 🐛 [TEST-STORE] Parsed service key structure: hasUaa(true), uaaKeys(url, clientid, clientsecret)
[INFO] ℹ️ [TEST-STORE] Authorization config loaded from /path/to/TRIAL.json: uaaUrl(https://...authentication...), clientId(test-client...)
[DEBUG] 🐛 [TEST-STORE] Reading env file: /path/to/TRIAL.env
[DEBUG] 🐛 [TEST-STORE] Env file read successfully, size: 245 bytes
[INFO] ℹ️ [TEST-STORE] Session loaded for TRIAL: token(2263 chars, eyJ0eXAiOiJKV1QiLCJqaWQiO...Q5ti7aYmEzItIDuLp7axNYo6w), refreshToken(fcc971e1cf1548629216a96b0680eb85-r), sapUrl(https://...abap...)

Note: Logging only works when a logger is explicitly provided. Stores will not output anything to console if no logger is passed.

Testing

The package includes both unit tests (with mocked file system) and integration tests (with real files).

Unit Tests

Unit tests use Jest with mocked file system operations:

npm test

Integration Tests

Integration tests work with real files from tests/test-config.yaml:

  1. Copy tests/test-config.yaml.template to tests/test-config.yaml
  2. Fill in real paths and destinations
  3. Run tests - integration tests will use real files if configured
auth_broker:
  paths:
    service_keys_dir: ~/.config/mcp-abap-adt/service-keys/
    sessions_dir: ~/.config/mcp-abap-adt/sessions/
  abap:
    destination: "TRIAL"
  xsuaa:
    btp_destination: "mcp"
    mcp_url: "https://..."

Integration tests will skip if test-config.yaml is not configured or contains placeholder values.

Architecture

File Operations

  • Service Key Stores use JsonFileHandler to read JSON files
  • Session Stores use EnvFileHandler to read/write .env files
  • All file writes are atomic (write to temp file, then rename)

Store Implementation

  • All stores implement IServiceKeyStore or ISessionStore interfaces from @mcp-abap-adt/interfaces
  • Stores accept a single directory path in constructor
  • File-based session stores automatically create directories in constructor if they don't exist
  • Session stores automatically create sessions when calling setConnectionConfig or setAuthorizationConfig (no need to call saveSession first)
  • In-memory stores (Safe*SessionStore) don't persist data to disk

Session Store Behavior

Session stores are designed to work seamlessly with AuthBroker:

  • Ready after construction: File-based stores create directory automatically, stores are ready to use immediately
  • Automatic session creation: Calling setConnectionConfig or setAuthorizationConfig on an empty store creates a new session
  • ABAP stores: Require serviceUrl when creating new session (from config or defaultServiceUrl parameter)
  • BTP/XSUAA stores: Require defaultServiceUrl in constructor (cannot be obtained from service key), used when creating new sessions if config.serviceUrl is not provided
  • Token updates: setConnectionConfig updates token if provided, preserves existing token if not provided
  • Session updates: When updating existing sessions, only config.serviceUrl is used if explicitly provided; defaultServiceUrl is never used to modify existing sessions

Dependencies

  • @mcp-abap-adt/interfaces (^0.1.4) - Interface definitions (IServiceKeyStore, ISessionStore, IConfig, IConnectionConfig, IAuthorizationConfig, ILogger)
  • dotenv - Environment variable parsing

License

MIT