{"version":3,"file":"index.cjs","names":["#value","#store","#agent","Agent","#credentials","#doFetch","#username","#password","#provider","#getRstsToken","#exchangeForUserToken","#certFile","#keyFile","#cert","#key","#pfxFile","#pfx","#passphrase","#provider","#getRstsToken","#exchangeForUserToken","#redirectUri","#provider","#exchangeCode","#initiateRedirect","#provider","#callbackPort","#openBrowser","#exchangeCode","#accessToken","#host","#auth","#apiVersion","#timeout","#autoRefresh","#ca","#verify","#storage","#connected","#httpClient","#tokenSet","#ensureValidToken","#tokenRefreshPromise","#host","#auth","#ca","#verify","#apiVersion","#httpClient","#a2aRequest","#ensureHttpClient"],"sources":["../src/types.ts","../src/errors.ts","../src/secret.ts","../src/utils.ts","../src/storage/memory.ts","../src/storage/session.ts","../src/storage/types.ts","../src/http/node.ts","../src/http/browser.ts","../src/auth/password.ts","../src/auth/certificate.ts","../src/auth/pkce.ts","../src/auth/pkce-noninteractive.ts","../src/auth/pkce-callback.ts","../src/auth/token.ts","../src/auth/anonymous.ts","../src/client.ts","../src/a2a/types.ts","../src/a2a/index.ts"],"sourcesContent":["/**\n * Safeguard appliance service endpoints.\n */\nexport enum Service {\n  CORE = 'core',\n  APPLIANCE = 'appliance',\n  NOTIFICATION = 'notification',\n  A2A = 'a2a',\n  EVENT = 'event',\n  RSTS = 'RSTS',\n}\n\n/**\n * HTTP methods supported by the Safeguard API.\n */\nexport enum HttpMethod {\n  GET = 'GET',\n  POST = 'POST',\n  PUT = 'PUT',\n  DELETE = 'DELETE',\n  PATCH = 'PATCH',\n}\n\n/**\n * Full response from a Safeguard API call (returned when fullResponse: true).\n */\nexport interface SafeguardResponse<T = unknown> {\n  data: T;\n  status: number;\n  headers: Record<string, string>;\n}\n\n/**\n * Options for individual API requests.\n */\nexport interface RequestOptions {\n  /** Request body as JSON-serializable object. */\n  json?: unknown;\n  /** Raw request body. */\n  body?: BodyInit | null;\n  /** Additional HTTP headers. */\n  headers?: Record<string, string>;\n  /** URL query parameters. */\n  query?: Record<string, string | number | boolean>;\n  /** AbortSignal for request cancellation. */\n  signal?: AbortSignal;\n  /** Request timeout in milliseconds (overrides client default). */\n  timeout?: number;\n  /** If true, returns full response with status and headers. */\n  fullResponse?: boolean;\n}\n\n/**\n * Options for constructing a SafeguardClient.\n */\nexport interface SafeguardClientOptions {\n  /** Authentication strategy. */\n  auth: import('./auth/types.js').Auth;\n  /** Custom CA certificate (PEM string or Buffer). Node.js only. */\n  ca?: string | Buffer;\n  /** Whether to verify TLS certificates. Default: true. */\n  verify?: boolean;\n  /** Safeguard API version prefix. Default: 'v4'. */\n  apiVersion?: string;\n  /** Request timeout in milliseconds. Default: 300_000 (5 min). */\n  timeout?: number;\n  /** Auto-refresh tokens before expiry. Default: true. */\n  autoRefresh?: boolean;\n}\n","/**\n * Error hierarchy for the Safeguard SDK.\n *\n * SafeguardError\n * ├── ApiError              (HTTP errors from Safeguard API)\n * │   ├── AuthenticationError  (401)\n * │   ├── AuthorizationError   (403)\n * │   └── NotFoundError        (404)\n * ├── TransportError        (Network/connection failures)\n * └── ConfigurationError    (Invalid client options)\n */\n\nexport class SafeguardError extends Error {\n  constructor(message: string, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'SafeguardError';\n  }\n}\n\nexport interface ApiErrorBody {\n  Code?: string;\n  Message?: string;\n  InnerError?: { Message?: string };\n  [key: string]: unknown;\n}\n\nexport class ApiError extends SafeguardError {\n  readonly status: number;\n  readonly body: ApiErrorBody | null;\n\n  constructor(message: string, status: number, body: ApiErrorBody | null = null, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'ApiError';\n    this.status = status;\n    this.body = body;\n  }\n\n  /**\n   * Creates an appropriate ApiError subclass based on HTTP status code.\n   */\n  static fromResponse(status: number, body: string | ApiErrorBody | null): ApiError {\n    const parsed = ApiError.parseBody(body);\n    const message = ApiError.buildMessage(status, parsed);\n\n    switch (status) {\n      case 401:\n        return new AuthenticationError(message, parsed);\n      case 403:\n        return new AuthorizationError(message, parsed);\n      case 404:\n        return new NotFoundError(message, parsed);\n      default:\n        return new ApiError(message, status, parsed);\n    }\n  }\n\n  private static parseBody(body: string | ApiErrorBody | null): ApiErrorBody | null {\n    if (body === null || body === undefined) return null;\n    if (typeof body === 'object') return body;\n    try {\n      return JSON.parse(body) as ApiErrorBody;\n    } catch {\n      return { Message: body };\n    }\n  }\n\n  private static buildMessage(status: number, body: ApiErrorBody | null): string {\n    const apiMessage = body?.Message ?? body?.InnerError?.Message;\n    if (apiMessage) {\n      return `HTTP ${String(status)}: ${apiMessage}`;\n    }\n    return `HTTP ${String(status)}`;\n  }\n}\n\nexport class AuthenticationError extends ApiError {\n  constructor(message: string, body: ApiErrorBody | null = null, options?: ErrorOptions) {\n    super(message, 401, body, options);\n    this.name = 'AuthenticationError';\n  }\n}\n\nexport class AuthorizationError extends ApiError {\n  constructor(message: string, body: ApiErrorBody | null = null, options?: ErrorOptions) {\n    super(message, 403, body, options);\n    this.name = 'AuthorizationError';\n  }\n}\n\nexport class NotFoundError extends ApiError {\n  constructor(message: string, body: ApiErrorBody | null = null, options?: ErrorOptions) {\n    super(message, 404, body, options);\n    this.name = 'NotFoundError';\n  }\n}\n\nexport class TransportError extends SafeguardError {\n  constructor(message: string, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'TransportError';\n  }\n}\n\nexport class ConfigurationError extends SafeguardError {\n  constructor(message: string, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'ConfigurationError';\n  }\n}\n","const REDACTED = '[REDACTED]';\n\n/**\n * A wrapper that prevents accidental logging of sensitive values.\n *\n * - `toString()` returns \"[REDACTED]\"\n * - `toJSON()` returns \"[REDACTED]\"\n * - `console.log(secretValue)` prints \"[REDACTED]\"\n * - `.expose()` returns the raw value when intentionally needed\n */\nexport class SecretValue {\n  readonly #value: string;\n\n  constructor(value: string) {\n    this.#value = value;\n  }\n\n  /** Returns the raw secret. Use only when you intentionally need the plaintext. */\n  expose(): string {\n    return this.#value;\n  }\n\n  toString(): string {\n    return REDACTED;\n  }\n\n  toJSON(): string {\n    return REDACTED;\n  }\n\n  /** Node.js custom inspect (prevents leaking in console.log / util.inspect). */\n  [Symbol.for('nodejs.util.inspect.custom')](): string {\n    return REDACTED;\n  }\n\n  get [Symbol.toStringTag](): string {\n    return 'SecretValue';\n  }\n}\n","import { Service } from './types.js';\nimport { ConfigurationError } from './errors.js';\n\n/**\n * Validates that a host string is a bare hostname or IP address.\n * Rejects URLs, paths, query strings, userinfo, and embedded ports.\n *\n * @throws {ConfigurationError} if the host contains disallowed characters\n */\nexport function validateHost(host: string): string {\n  if (!host) throw new ConfigurationError('Host must not be empty');\n\n  const trimmed = host.trim();\n  if (trimmed !== host) {\n    throw new ConfigurationError('Host must not contain leading or trailing whitespace');\n  }\n\n  // Reject protocol prefixes\n  if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(host)) {\n    throw new ConfigurationError(\n      `Host must be a bare hostname or IP, not a URL. Remove the protocol prefix (e.g., use \"${host.replace(/^[a-z][a-z0-9+.-]*:\\/\\//i, '')}\")`,\n    );\n  }\n\n  // Reject path, query, fragment, userinfo characters\n  if (/[/?#@]/.test(host)) {\n    throw new ConfigurationError(\n      'Host must be a bare hostname or IP address — must not contain /, ?, #, or @',\n    );\n  }\n\n  // Reject port suffix (e.g. \"host:8443\") — SDK always uses HTTPS/443\n  if (/:\\d+$/.test(host) && !host.startsWith('[')) {\n    throw new ConfigurationError(\n      'Host must not include a port number. The SDK always connects over HTTPS (port 443).',\n    );\n  }\n\n  return host;\n}\n\n/**\n * Builds the base URL for a Safeguard service endpoint.\n *\n * @example\n * buildServiceUrl('appliance.example.com', Service.CORE)\n * // => 'https://appliance.example.com/service/core/v4'\n */\nexport function buildServiceUrl(host: string, service: Service, apiVersion: string = 'v4'): string {\n  if (service === Service.RSTS) {\n    return `https://${host}/RSTS`;\n  }\n  return `https://${host}/service/${service}/${apiVersion}`;\n}\n\n/**\n * Builds a full API URL including path and optional query parameters.\n *\n * @example\n * buildRequestUrl('appliance.example.com', Service.CORE, 'Users', { filter: 'Name eq \"admin\"' })\n * // => 'https://appliance.example.com/service/core/v4/Users?filter=Name+eq+%22admin%22'\n */\nexport function buildRequestUrl(\n  host: string,\n  service: Service,\n  relativeUrl: string,\n  query?: Record<string, string | number | boolean>,\n  apiVersion: string = 'v4',\n): string {\n  const base = buildServiceUrl(host, service, apiVersion);\n  const path = relativeUrl.startsWith('/') ? relativeUrl.slice(1) : relativeUrl;\n  const url = new URL(`${base}/${path}`);\n\n  if (query) {\n    for (const [key, value] of Object.entries(query)) {\n      url.searchParams.set(key, String(value));\n    }\n  }\n\n  return url.toString();\n}\n\n/**\n * Encodes bytes to a URL-safe base64 string (no padding).\n */\nexport function base64UrlEncode(bytes: Uint8Array): string {\n  const binary = String.fromCharCode(...bytes);\n  return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/**\n * Generates a cryptographically random code verifier for PKCE.\n * Returns a 43-character base64url string (32 random bytes).\n */\nexport function generateCodeVerifier(): string {\n  const bytes = new Uint8Array(32);\n  crypto.getRandomValues(bytes);\n  return base64UrlEncode(bytes);\n}\n\n/**\n * Computes the S256 code challenge from a code verifier.\n * Uses Web Crypto API (available in Node 20+ and all modern browsers).\n */\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n  const encoder = new TextEncoder();\n  const data = encoder.encode(verifier);\n  const digest = await crypto.subtle.digest('SHA-256', data);\n  return base64UrlEncode(new Uint8Array(digest));\n}\n\n/**\n * Generates a random state parameter for OAuth flows.\n */\nexport function generateState(): string {\n  const bytes = new Uint8Array(16);\n  crypto.getRandomValues(bytes);\n  return base64UrlEncode(bytes);\n}\n\n/**\n * Extracts the `exp` claim from a JWT and returns expiresIn (seconds from now).\n * Returns undefined if the token is not a valid JWT or has no `exp` claim.\n */\nexport function getTokenExpiresIn(jwt: string): number | undefined {\n  try {\n    const parts = jwt.split('.');\n    if (parts.length !== 3) return undefined;\n    // Base64url decode the payload\n    const payload = parts[1]!.replace(/-/g, '+').replace(/_/g, '/');\n    const json = atob(payload);\n    const claims = JSON.parse(json) as { exp?: number };\n    if (typeof claims.exp !== 'number') return undefined;\n    const now = Math.floor(Date.now() / 1000);\n    return Math.max(0, claims.exp - now);\n  } catch {\n    return undefined;\n  }\n}\n","import type { StorageProvider } from './types.js';\n\n/**\n * In-memory storage provider. Default for Node.js environments.\n * Data does not persist across process restarts.\n */\nexport class MemoryStorage implements StorageProvider {\n  readonly #store = new Map<string, string>();\n\n  get(key: string): string | null {\n    return this.#store.get(key) ?? null;\n  }\n\n  set(key: string, value: string): void {\n    this.#store.set(key, value);\n  }\n\n  remove(key: string): void {\n    this.#store.delete(key);\n  }\n\n  clear(): void {\n    this.#store.clear();\n  }\n}\n","import type { StorageProvider } from './types.js';\n\n/**\n * Browser sessionStorage adapter. Data persists for the browser tab lifetime.\n * Requires a DOM environment (browser or jsdom).\n */\nexport class BrowserSessionStorage implements StorageProvider {\n  get(key: string): string | null {\n    return sessionStorage.getItem(key);\n  }\n\n  set(key: string, value: string): void {\n    sessionStorage.setItem(key, value);\n  }\n\n  remove(key: string): void {\n    sessionStorage.removeItem(key);\n  }\n\n  clear(): void {\n    sessionStorage.clear();\n  }\n}\n","/**\n * Interface for token/state storage backends.\n */\nexport interface StorageProvider {\n  get(key: string): string | null;\n  set(key: string, value: string): void;\n  remove(key: string): void;\n  clear(): void;\n}\n\n/** Well-known storage keys used by the SDK. */\nexport const StorageKeys = {\n  STATE: 'safeguard_state',\n  CODE_VERIFIER: 'safeguard_code_verifier',\n} as const;\n","import { Agent, request as undiciRequest } from 'undici';\nimport type { HttpClient, HttpRequestOptions, HttpResponse, TlsOptions } from './types.js';\n\n/**\n * Node.js HTTP client using undici for full TLS control.\n * Creates a per-instance Agent — no global state mutation.\n */\nexport class NodeHttpClient implements HttpClient {\n  readonly #agent: Agent;\n\n  constructor(tlsOptions?: TlsOptions) {\n    this.#agent = new Agent({\n      connect: {\n        ca: tlsOptions?.ca,\n        cert: tlsOptions?.cert,\n        key: tlsOptions?.key,\n        passphrase: tlsOptions?.passphrase,\n        rejectUnauthorized: tlsOptions?.rejectUnauthorized ?? true,\n      },\n    });\n  }\n\n  async request(options: HttpRequestOptions): Promise<HttpResponse> {\n    const { url, method, headers, body, signal, timeout } = options;\n\n    const requestOptions: Parameters<typeof undiciRequest>[1] = {\n      method: method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n      dispatcher: this.#agent,\n    };\n\n    if (headers) requestOptions.headers = headers;\n    if (body != null) requestOptions.body = body;\n    if (signal) requestOptions.signal = signal;\n    if (timeout) {\n      requestOptions.bodyTimeout = timeout;\n      requestOptions.headersTimeout = timeout;\n    }\n\n    const response = await undiciRequest(url, requestOptions);\n\n    const responseHeaders: Record<string, string> = {};\n    const rawHeaders = response.headers;\n    for (const [key, value] of Object.entries(rawHeaders)) {\n      if (value !== undefined) {\n        responseHeaders[key] = Array.isArray(value) ? value.join(', ') : value;\n      }\n    }\n\n    const responseBody = await response.body.text();\n\n    return {\n      status: response.statusCode,\n      headers: responseHeaders,\n      body: responseBody,\n    };\n  }\n\n  dispose(): void {\n    this.#agent.close().catch(() => { /* already closed or destroyed */ });\n  }\n}\n","import type { HttpClient, HttpRequestOptions, HttpResponse } from './types.js';\n\n/**\n * Browser HTTP client using native fetch API.\n * No TLS configuration needed — browser handles certificates.\n */\nexport class BrowserHttpClient implements HttpClient {\n  readonly #credentials: RequestCredentials;\n\n  constructor(options?: { credentials?: RequestCredentials }) {\n    this.#credentials = options?.credentials ?? 'include';\n  }\n\n  async request(options: HttpRequestOptions): Promise<HttpResponse> {\n    const { url, method, headers, body, signal, timeout } = options;\n\n    const requestInit: RequestInit = {\n      method,\n      credentials: this.#credentials,\n    };\n\n    if (headers) requestInit.headers = headers;\n    if (body != null) requestInit.body = body as BodyInit;\n    if (signal || timeout) {\n      const controller = new AbortController();\n      let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n      if (timeout) {\n        timeoutId = setTimeout(() => controller.abort(new Error('Request timed out')), timeout);\n      }\n\n      requestInit.signal = signal\n        ? AbortSignal.any([signal, controller.signal])\n        : controller.signal;\n\n      try {\n        return await this.#doFetch(url, requestInit);\n      } finally {\n        if (timeoutId !== undefined) clearTimeout(timeoutId);\n      }\n    }\n\n    return this.#doFetch(url, requestInit);\n  }\n\n  async #doFetch(url: string, init: RequestInit): Promise<HttpResponse> {\n    const response = await fetch(url, init);\n\n    const responseHeaders: Record<string, string> = {};\n    response.headers.forEach((value, key) => {\n      responseHeaders[key] = value;\n    });\n\n    const responseBody = await response.text();\n\n    return {\n      status: response.status,\n      headers: responseHeaders,\n      body: responseBody,\n    };\n  }\n}\n","import type { HttpClient } from '../http/types.js';\nimport type { StorageProvider } from '../storage/types.js';\nimport type { Auth, TokenSet } from './types.js';\nimport { ConfigurationError } from '../errors.js';\nimport { SecretValue } from '../secret.js';\nimport { getTokenExpiresIn } from '../utils.js';\n\nexport interface PasswordAuthOptions {\n  username: string;\n  password: string;\n  /** Identity provider name. Default: 'local'. */\n  provider?: string;\n}\n\n/**\n * Authenticates using username/password via RSTS Resource Owner grant.\n */\nexport class PasswordAuth implements Auth {\n  readonly #username: string;\n  readonly #password: SecretValue;\n  readonly #provider: string;\n\n  constructor(options: PasswordAuthOptions) {\n    if (!options.username) throw new ConfigurationError('PasswordAuth requires username');\n    if (!options.password) throw new ConfigurationError('PasswordAuth requires password');\n    if (!options.provider) throw new ConfigurationError('PasswordAuth requires provider');\n    this.#username = options.username;\n    this.#password = new SecretValue(options.password);\n    this.#provider = options.provider;\n  }\n\n  get description(): string {\n    return `PasswordAuth(${this.#username}@${this.#provider})`;\n  }\n\n  async authenticate(host: string, httpClient: HttpClient, _storage: StorageProvider): Promise<TokenSet> {\n    // Step 1: Get RSTS token\n    const rstsToken = await this.#getRstsToken(host, httpClient);\n\n    // Step 2: Exchange RSTS token for Safeguard user token\n    const userToken = await this.#exchangeForUserToken(host, httpClient, rstsToken);\n\n    return userToken;\n  }\n\n  async refreshToken(host: string, httpClient: HttpClient, storage: StorageProvider): Promise<TokenSet | null> {\n    // Password auth can always re-authenticate\n    return this.authenticate(host, httpClient, storage);\n  }\n\n  async #getRstsToken(host: string, httpClient: HttpClient): Promise<string> {\n    const body = JSON.stringify({\n      grant_type: 'password',\n      username: this.#username,\n      password: this.#password.expose(),\n      scope: 'rsts:sts:primaryproviderid:' + this.#provider.toLowerCase(),\n    });\n\n    const response = await httpClient.request({\n      url: `https://${host}/RSTS/oauth2/token`,\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body,\n    });\n\n    if (response.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    const data = JSON.parse(response.body) as { access_token: string };\n    return data.access_token;\n  }\n\n  async #exchangeForUserToken(host: string, httpClient: HttpClient, rstsToken: string): Promise<TokenSet> {\n    const response = await httpClient.request({\n      url: `https://${host}/service/core/v4/Token/LoginResponse`,\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${rstsToken}`,\n      },\n      body: JSON.stringify({ StsAccessToken: rstsToken }),\n    });\n\n    if (response.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    const data = JSON.parse(response.body) as { UserToken: string; ExpiresIn?: number };\n    const tokenSet: TokenSet = {\n      accessToken: new SecretValue(data.UserToken),\n      acquiredAt: Date.now(),\n    };\n    if (data.ExpiresIn != null) {\n      tokenSet.expiresIn = data.ExpiresIn;\n    } else {\n      const expiresIn = getTokenExpiresIn(data.UserToken);\n      if (expiresIn != null) tokenSet.expiresIn = expiresIn;\n    }\n    return tokenSet;\n  }\n}\n","import type { HttpClient } from '../http/types.js';\nimport type { StorageProvider } from '../storage/types.js';\nimport type { Auth, TokenSet } from './types.js';\nimport { ConfigurationError } from '../errors.js';\nimport { SecretValue } from '../secret.js';\nimport { getTokenExpiresIn } from '../utils.js';\n\nexport interface CertificateAuthOptions {\n  /** Path to PEM certificate file, or PEM string. */\n  certFile?: string;\n  /** Path to PEM private key file, or PEM string. */\n  keyFile?: string;\n  /** PEM certificate content (alternative to certFile). */\n  cert?: string | Buffer;\n  /** PEM key content (alternative to keyFile). */\n  key?: string | Buffer;\n  /** Path to PFX/PKCS12 file (alternative to cert+key). */\n  pfxFile?: string;\n  /** PFX/PKCS12 content (alternative to cert+key). */\n  pfx?: string | Buffer;\n  /** Passphrase for encrypted private key or PFX. */\n  passphrase?: string;\n  /** Identity provider name. Default: 'certificate'. */\n  provider?: string;\n}\n\n/**\n * Authenticates using a client certificate (mTLS) against RSTS.\n * Node.js only — requires TLS client cert support in HttpClient.\n */\nexport class CertificateAuth implements Auth {\n  readonly #certFile: string | undefined;\n  readonly #keyFile: string | undefined;\n  readonly #cert: string | Buffer | undefined;\n  readonly #key: string | Buffer | undefined;\n  readonly #pfxFile: string | undefined;\n  readonly #pfx: string | Buffer | undefined;\n  readonly #passphrase: SecretValue | undefined;\n  readonly #provider: string;\n\n  constructor(options: CertificateAuthOptions) {\n    const hasPfx = options.pfx ?? options.pfxFile;\n    const hasCert = options.cert ?? options.certFile;\n    const hasKey = options.key ?? options.keyFile;\n    if (!hasPfx && !hasCert) throw new ConfigurationError('CertificateAuth requires cert/certFile or pfxFile/pfx');\n    if (!hasPfx && !hasKey) throw new ConfigurationError('CertificateAuth requires key or keyFile');\n    this.#certFile = options.certFile;\n    this.#keyFile = options.keyFile;\n    this.#cert = options.cert;\n    this.#key = options.key;\n    this.#pfxFile = options.pfxFile;\n    this.#pfx = options.pfx;\n    this.#passphrase = options.passphrase ? new SecretValue(options.passphrase) : undefined;\n    this.#provider = options.provider ?? 'certificate';\n  }\n\n  get description(): string {\n    return `CertificateAuth(${this.#provider})`;\n  }\n\n  /** Returns the TLS options needed to create an mTLS HttpClient. */\n  getTlsOptions(): { cert?: string | Buffer; key?: string | Buffer; pfx?: string | Buffer; passphrase?: string } {\n    const opts: { cert?: string | Buffer; key?: string | Buffer; pfx?: string | Buffer; passphrase?: string } = {};\n    if (this.#pfx ?? this.#pfxFile) {\n      opts.pfx = this.#pfx ?? this.#pfxFile!;\n    } else {\n      opts.cert = this.#cert ?? this.#certFile!;\n      opts.key = this.#key ?? this.#keyFile!;\n    }\n    if (this.#passphrase) opts.passphrase = this.#passphrase.expose();\n    return opts;\n  }\n\n  async authenticate(host: string, httpClient: HttpClient, _storage: StorageProvider): Promise<TokenSet> {\n    // Step 1: Get RSTS token using client cert (mTLS)\n    const rstsToken = await this.#getRstsToken(host, httpClient);\n\n    // Step 2: Exchange RSTS token for Safeguard user token\n    return this.#exchangeForUserToken(host, httpClient, rstsToken);\n  }\n\n  async refreshToken(host: string, httpClient: HttpClient, storage: StorageProvider): Promise<TokenSet | null> {\n    return this.authenticate(host, httpClient, storage);\n  }\n\n  async #getRstsToken(host: string, httpClient: HttpClient): Promise<string> {\n    const body = JSON.stringify({\n      grant_type: 'client_credentials',\n      scope: 'rsts:sts:primaryproviderid:' + this.#provider.toLowerCase(),\n    });\n\n    const response = await httpClient.request({\n      url: `https://${host}/RSTS/oauth2/token`,\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body,\n    });\n\n    if (response.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    const data = JSON.parse(response.body) as { access_token: string };\n    return data.access_token;\n  }\n\n  async #exchangeForUserToken(host: string, httpClient: HttpClient, rstsToken: string): Promise<TokenSet> {\n    const response = await httpClient.request({\n      url: `https://${host}/service/core/v4/Token/LoginResponse`,\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${rstsToken}`,\n      },\n      body: JSON.stringify({ StsAccessToken: rstsToken }),\n    });\n\n    if (response.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    const data = JSON.parse(response.body) as { UserToken: string; ExpiresIn?: number };\n    const tokenSet: TokenSet = {\n      accessToken: new SecretValue(data.UserToken),\n      acquiredAt: Date.now(),\n    };\n    if (data.ExpiresIn != null) {\n      tokenSet.expiresIn = data.ExpiresIn;\n    } else {\n      const expiresIn = getTokenExpiresIn(data.UserToken);\n      if (expiresIn != null) tokenSet.expiresIn = expiresIn;\n    }\n    return tokenSet;\n  }\n}\n","import type { HttpClient } from '../http/types.js';\nimport type { StorageProvider } from '../storage/types.js';\nimport type { Auth, TokenSet } from './types.js';\nimport { ConfigurationError } from '../errors.js';\nimport { SecretValue } from '../secret.js';\nimport { StorageKeys } from '../storage/types.js';\nimport { generateCodeVerifier, generateCodeChallenge, generateState } from '../utils.js';\n\nexport interface PkceAuthOptions {\n  /** OAuth redirect URI (must match RSTS configuration). */\n  redirectUri: string;\n  /** Identity provider name. Default: 'local'. */\n  provider?: string;\n}\n\n/**\n * Authenticates using PKCE (Proof Key for Code Exchange) with browser redirect.\n * For browser environments where the user is redirected to RSTS login.\n */\nexport class PkceAuth implements Auth {\n  readonly #redirectUri: string;\n  readonly #provider: string;\n\n  constructor(options: PkceAuthOptions) {\n    if (!options.redirectUri) throw new ConfigurationError('PkceAuth requires redirectUri');\n    if (!options.provider) throw new ConfigurationError('PkceAuth requires provider');\n    this.#redirectUri = options.redirectUri;\n    this.#provider = options.provider;\n  }\n\n  get description(): string {\n    return `PKCE(redirect=${this.#redirectUri})`;\n  }\n\n  /**\n   * Initiates the PKCE flow. If a stored authorization code exists (from callback),\n   * exchanges it for a token. Otherwise, redirects to RSTS login.\n   */\n  async authenticate(host: string, httpClient: HttpClient, storage: StorageProvider): Promise<TokenSet> {\n    // Check for authorization code (set by handlePkceCallback)\n    const code = storage.get('safeguard_auth_code');\n    if (code) {\n      const verifier = storage.get(StorageKeys.CODE_VERIFIER);\n      if (!verifier) {\n        throw new ConfigurationError('PKCE code verifier not found in storage');\n      }\n      storage.remove('safeguard_auth_code');\n      storage.remove(StorageKeys.CODE_VERIFIER);\n      storage.remove(StorageKeys.STATE);\n      return this.#exchangeCode(host, httpClient, code, verifier);\n    }\n\n    // No code — initiate redirect\n    await this.#initiateRedirect(host, storage);\n\n    // This point is never reached in a browser (redirect happens).\n    // For testability, throw rather than hang.\n    throw new ConfigurationError(\n      'PKCE redirect initiated. Call handlePkceCallback() on the callback page.',\n    );\n  }\n\n  async #initiateRedirect(host: string, storage: StorageProvider): Promise<void> {\n    const verifier = generateCodeVerifier();\n    const challenge = await generateCodeChallenge(verifier);\n    const state = generateState();\n\n    storage.set(StorageKeys.CODE_VERIFIER, verifier);\n    storage.set(StorageKeys.STATE, state);\n\n    const params = new URLSearchParams({\n      response_type: 'code',\n      client_id: 'safeguard.js',\n      redirect_uri: this.#redirectUri,\n      scope: 'rsts:sts:primaryproviderid:' + this.#provider,\n      code_challenge: challenge,\n      code_challenge_method: 'S256',\n      state,\n    });\n\n    const authUrl = `https://${host}/RSTS/Login?${params.toString()}`;\n\n    // In browser environment, redirect\n    if (typeof window !== 'undefined' && window.location) {\n      window.location.href = authUrl;\n    }\n  }\n\n  async #exchangeCode(\n    host: string,\n    httpClient: HttpClient,\n    code: string,\n    verifier: string,\n  ): Promise<TokenSet> {\n    const body = new URLSearchParams({\n      grant_type: 'authorization_code',\n      code,\n      redirect_uri: this.#redirectUri,\n      client_id: 'safeguard.js',\n      code_verifier: verifier,\n    });\n\n    const response = await httpClient.request({\n      url: `https://${host}/RSTS/oauth2/token`,\n      method: 'POST',\n      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n      body: body.toString(),\n    });\n\n    if (response.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    const data = JSON.parse(response.body) as { access_token: string; expires_in?: number };\n\n    // Exchange RSTS token for Safeguard user token\n    const userTokenResponse = await httpClient.request({\n      url: `https://${host}/service/core/v4/Token/LoginResponse`,\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${data.access_token}`,\n      },\n      body: JSON.stringify({ StsAccessToken: data.access_token }),\n    });\n\n    if (userTokenResponse.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(userTokenResponse.status, userTokenResponse.body);\n    }\n\n    const userData = JSON.parse(userTokenResponse.body) as { UserToken: string; ExpiresIn?: number };\n    const tokenSet: TokenSet = {\n      accessToken: new SecretValue(userData.UserToken),\n      acquiredAt: Date.now(),\n    };\n    if (userData.ExpiresIn != null) tokenSet.expiresIn = userData.ExpiresIn;\n\n    // Token stays in-memory only (SafeguardClient.#tokenSet). Not persisted to\n    // sessionStorage to avoid XSS exfiltration of high-privilege PAM tokens.\n    return tokenSet;\n  }\n}\n","import type { HttpClient } from '../http/types.js';\nimport type { StorageProvider } from '../storage/types.js';\nimport type { Auth, TokenSet } from './types.js';\nimport { ConfigurationError } from '../errors.js';\nimport { SecretValue } from '../secret.js';\nimport { generateCodeVerifier, generateCodeChallenge, generateState } from '../utils.js';\n\nexport interface PkceNonInteractiveAuthOptions {\n  /** Identity provider name. Default: 'local'. */\n  provider?: string;\n  /** Port for the local callback server. Default: 8400. */\n  callbackPort?: number;\n}\n\n/**\n * Non-interactive PKCE authentication for Node.js automation.\n * Starts a local HTTP server to receive the callback, opens the system browser\n * for login, and waits for the redirect.\n *\n * Matches PySafeguard's PkceAuth behavior (local server pattern).\n */\nexport class PkceNonInteractiveAuth implements Auth {\n  readonly #provider: string;\n  readonly #callbackPort: number;\n\n  constructor(options?: PkceNonInteractiveAuthOptions) {\n    this.#provider = options?.provider ?? 'local';\n    this.#callbackPort = options?.callbackPort ?? 8400;\n  }\n\n  get description(): string {\n    return `PkceNonInteractiveAuth(port=${String(this.#callbackPort)})`;\n  }\n\n  async authenticate(host: string, httpClient: HttpClient, _storage: StorageProvider): Promise<TokenSet> {\n    const { createServer } = await import('node:http');\n    const { once } = await import('node:events');\n\n    const verifier = generateCodeVerifier();\n    const challenge = await generateCodeChallenge(verifier);\n    const state = generateState();\n    const redirectUri = `http://localhost:${String(this.#callbackPort)}/callback`;\n\n    // Start local server to receive callback.\n    // Bind explicitly to the loopback interface (127.0.0.1) so a co-resident\n    // process on a shared host cannot intercept the authorization code by\n    // racing the legitimate browser callback on the ephemeral port.\n    const server = createServer();\n    server.listen(this.#callbackPort, '127.0.0.1');\n\n    const params = new URLSearchParams({\n      response_type: 'code',\n      client_id: 'safeguard.js',\n      redirect_uri: redirectUri,\n      scope: 'rsts:sts:primaryproviderid:' + this.#provider,\n      code_challenge: challenge,\n      code_challenge_method: 'S256',\n      state,\n    });\n\n    const authUrl = `https://${host}/RSTS/Login?${params.toString()}`;\n\n    // Open browser\n    await this.#openBrowser(authUrl);\n\n    // Wait for callback\n    const code = await new Promise<string>((resolve, reject) => {\n      const timeout = setTimeout(() => {\n        server.close();\n        reject(new ConfigurationError('PKCE callback timed out after 120 seconds'));\n      }, 120_000);\n\n      server.on('request', (req, res) => {\n        const url = new URL(req.url ?? '/', `http://localhost:${String(this.#callbackPort)}`);\n        if (url.pathname === '/callback') {\n          const receivedCode = url.searchParams.get('code');\n          const receivedState = url.searchParams.get('state');\n\n          if (receivedState !== state) {\n            res.writeHead(400, { 'Content-Type': 'text/plain' });\n            res.end('State mismatch');\n            clearTimeout(timeout);\n            server.close();\n            reject(new ConfigurationError('PKCE state mismatch'));\n            return;\n          }\n\n          if (!receivedCode) {\n            res.writeHead(400, { 'Content-Type': 'text/plain' });\n            res.end('No authorization code received');\n            clearTimeout(timeout);\n            server.close();\n            reject(new ConfigurationError('No authorization code in callback'));\n            return;\n          }\n\n          res.writeHead(200, { 'Content-Type': 'text/html' });\n          res.end('<html><body><h1>Authentication successful!</h1><p>You may close this window.</p></body></html>');\n          clearTimeout(timeout);\n          server.close();\n          resolve(receivedCode);\n        }\n      });\n\n      once(server, 'error').then(([err]) => {\n        clearTimeout(timeout);\n        reject(err as Error);\n      }).catch(reject);\n    });\n\n    // Exchange code for token\n    return this.#exchangeCode(host, httpClient, code, verifier, redirectUri);\n  }\n\n  async #exchangeCode(\n    host: string,\n    httpClient: HttpClient,\n    code: string,\n    verifier: string,\n    redirectUri: string,\n  ): Promise<TokenSet> {\n    const body = new URLSearchParams({\n      grant_type: 'authorization_code',\n      code,\n      redirect_uri: redirectUri,\n      client_id: 'safeguard.js',\n      code_verifier: verifier,\n    });\n\n    const response = await httpClient.request({\n      url: `https://${host}/RSTS/oauth2/token`,\n      method: 'POST',\n      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n      body: body.toString(),\n    });\n\n    if (response.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    const data = JSON.parse(response.body) as { access_token: string };\n\n    // Exchange for user token\n    const userResponse = await httpClient.request({\n      url: `https://${host}/service/core/v4/Token/LoginResponse`,\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${data.access_token}`,\n      },\n      body: JSON.stringify({ StsAccessToken: data.access_token }),\n    });\n\n    if (userResponse.status !== 200) {\n      const { ApiError } = await import('../errors.js');\n      throw ApiError.fromResponse(userResponse.status, userResponse.body);\n    }\n\n    const userData = JSON.parse(userResponse.body) as { UserToken: string; ExpiresIn?: number };\n    const tokenSet: TokenSet = {\n      accessToken: new SecretValue(userData.UserToken),\n      acquiredAt: Date.now(),\n    };\n    if (userData.ExpiresIn != null) tokenSet.expiresIn = userData.ExpiresIn;\n    return tokenSet;\n  }\n\n  async #openBrowser(url: string): Promise<void> {\n    const { platform } = await import('node:os');\n    const { execFile } = await import('node:child_process');\n\n    // Use execFile with argument arrays to prevent shell injection via host parameter\n    if (platform() === 'win32') {\n      execFile('cmd', ['/c', 'start', '', url]);\n    } else if (platform() === 'darwin') {\n      execFile('open', [url]);\n    } else {\n      execFile('xdg-open', [url]);\n    }\n  }\n}\n","import { StorageKeys } from '../storage/types.js';\nimport type { StorageProvider } from '../storage/types.js';\nimport { ConfigurationError } from '../errors.js';\n\nexport interface PkceCallbackResult {\n  code: string;\n  state: string;\n}\n\n/**\n * Parses the PKCE callback URL and stores the authorization code.\n * Call this on the callback/redirect page to complete the PKCE flow.\n *\n * This is the explicit replacement for the legacy `safeguardJsAccessTokenChecker.js`\n * script that ran as a side-effect on import.\n *\n * @param storage - StorageProvider to persist the code\n * @param url - The callback URL to parse (defaults to window.location.href)\n * @returns The parsed code and state, or null if not a valid callback\n */\nexport function handlePkceCallback(\n  storage: StorageProvider,\n  url?: string,\n): PkceCallbackResult | null {\n  const callbackUrl = url ?? (typeof window !== 'undefined' ? window.location.href : '');\n  if (!callbackUrl) return null;\n\n  const parsed = new URL(callbackUrl);\n  const code = parsed.searchParams.get('code');\n  const state = parsed.searchParams.get('state');\n\n  if (!code || !state) return null;\n\n  // Validate state matches what we stored\n  const storedState = storage.get(StorageKeys.STATE);\n  if (storedState && storedState !== state) {\n    throw new ConfigurationError('PKCE state mismatch — possible CSRF attack');\n  }\n\n  // Store the code for the PkceAuth strategy to pick up\n  storage.set('safeguard_auth_code', code);\n\n  return { code, state };\n}\n","import type { HttpClient } from '../http/types.js';\nimport type { StorageProvider } from '../storage/types.js';\nimport type { Auth, TokenSet } from './types.js';\nimport { ConfigurationError } from '../errors.js';\nimport { SecretValue } from '../secret.js';\n\nexport interface TokenAuthOptions {\n  /** Pre-existing Safeguard access token. */\n  accessToken: string;\n}\n\n/**\n * Uses a pre-existing access token. No authentication flow — the token is assumed valid.\n * Useful when tokens are obtained externally or for service-to-service scenarios.\n */\nexport class TokenAuth implements Auth {\n  readonly #accessToken: SecretValue;\n\n  constructor(options: TokenAuthOptions) {\n    if (!options.accessToken) throw new ConfigurationError('TokenAuth requires accessToken');\n    this.#accessToken = new SecretValue(options.accessToken);\n  }\n\n  get description(): string {\n    return 'TokenAuth(pre-existing)';\n  }\n\n  async authenticate(_host: string, _httpClient: HttpClient, _storage: StorageProvider): Promise<TokenSet> {\n    return {\n      accessToken: this.#accessToken,\n      acquiredAt: Date.now(),\n    };\n  }\n\n  // No refresh possible with a pre-existing token\n}\n","import type { HttpClient } from '../http/types.js';\nimport type { StorageProvider } from '../storage/types.js';\nimport type { Auth, TokenSet } from './types.js';\nimport { SecretValue } from '../secret.js';\n\n/**\n * Anonymous authentication — no credentials.\n * Used for accessing public Safeguard endpoints (e.g., appliance status).\n */\nexport class AnonymousAuth implements Auth {\n  get description(): string {\n    return 'AnonymousAuth';\n  }\n\n  async authenticate(_host: string, _httpClient: HttpClient, _storage: StorageProvider): Promise<TokenSet> {\n    return {\n      accessToken: new SecretValue(''),\n      acquiredAt: Date.now(),\n    };\n  }\n}\n","import { Service, HttpMethod } from './types.js';\nimport type { RequestOptions, SafeguardClientOptions } from './types.js';\nimport type { Auth, TokenSet } from './auth/types.js';\nimport type { HttpClient } from './http/types.js';\nimport type { StorageProvider } from './storage/types.js';\nimport { MemoryStorage } from './storage/memory.js';\nimport { buildRequestUrl, validateHost } from './utils.js';\nimport { AuthenticationError, ConfigurationError, ApiError } from './errors.js';\n\nconst DEFAULT_TIMEOUT = 300_000;\nconst DEFAULT_API_VERSION = 'v4';\nconst TOKEN_REFRESH_MARGIN_MS = 60_000; // refresh 60s before expiry\n\n/**\n * Main entry point for the Safeguard SDK.\n * Instance-based — no global state. Multiple clients to different appliances are supported.\n */\nexport class SafeguardClient {\n  readonly #host: string;\n  readonly #auth: Auth;\n  readonly #apiVersion: string;\n  readonly #timeout: number;\n  readonly #autoRefresh: boolean;\n  readonly #ca: string | Buffer | undefined;\n  readonly #verify: boolean;\n\n  #httpClient: HttpClient | undefined;\n  #storage: StorageProvider;\n  #tokenSet: TokenSet | undefined;\n  #connected = false;\n  /** Single-flight refresh promise to prevent thundering herd on token expiry. */\n  #tokenRefreshPromise: Promise<void> | undefined;\n\n  constructor(host: string, options: SafeguardClientOptions) {\n    if (!host) throw new ConfigurationError('SafeguardClient requires a host');\n    if (!options.auth) throw new ConfigurationError('SafeguardClient requires an auth strategy');\n    this.#host = validateHost(host);\n    this.#auth = options.auth;\n    this.#apiVersion = options.apiVersion ?? DEFAULT_API_VERSION;\n    this.#timeout = options.timeout ?? DEFAULT_TIMEOUT;\n    this.#autoRefresh = options.autoRefresh !== false;\n    this.#ca = options.ca;\n    this.#verify = options.verify !== false;\n    this.#storage = new MemoryStorage();\n  }\n\n  /** The appliance hostname this client connects to. */\n  get host(): string {\n    return this.#host;\n  }\n\n  /** The API version prefix (e.g. 'v4'). */\n  get apiVersion(): string {\n    return this.#apiVersion;\n  }\n\n  /** Custom CA certificate, if provided. */\n  get ca(): string | Buffer | undefined {\n    return this.#ca;\n  }\n\n  /** Whether TLS verification is enabled. */\n  get verify(): boolean {\n    return this.#verify;\n  }\n\n  /** Whether the client has an active authenticated session. */\n  get isConnected(): boolean {\n    return this.#connected;\n  }\n\n  /**\n   * Sets a custom StorageProvider (e.g., BrowserSessionStorage).\n   * Must be called before connect().\n   */\n  setStorage(storage: StorageProvider): this {\n    this.#storage = storage;\n    return this;\n  }\n\n  /**\n   * Sets the HttpClient implementation. If not called, must be set before connect().\n   * The factory pattern allows platform-specific client injection:\n   *   - Node: `new NodeHttpClient({ ca, rejectUnauthorized })`\n   *   - Browser: `new BrowserHttpClient()`\n   */\n  setHttpClient(httpClient: HttpClient): this {\n    this.#httpClient = httpClient;\n    return this;\n  }\n\n  /**\n   * Authenticate and establish a session.\n   * @throws {AuthenticationError} if authentication fails\n   * @throws {ConfigurationError} if httpClient not set\n   */\n  async connect(): Promise<void> {\n    if (!this.#httpClient) {\n      throw new ConfigurationError(\n        'HttpClient not set. Call setHttpClient() before connect(), or use SafeguardClient.createNode() / SafeguardClient.createBrowser().',\n      );\n    }\n\n    this.#tokenSet = await this.#auth.authenticate(this.#host, this.#httpClient, this.#storage);\n    if (!this.#tokenSet.accessToken.expose()) {\n      throw new AuthenticationError('Authentication returned empty access token');\n    }\n    this.#connected = true;\n  }\n\n  /**\n   * Disconnect — dispose HTTP client and clear token.\n   */\n  async disconnect(): Promise<void> {\n    this.#tokenSet = undefined;\n    this.#connected = false;\n    this.#httpClient?.dispose?.();\n  }\n\n  /**\n   * Returns seconds until the current access token expires, or -1 if unknown.\n   */\n  getAccessTokenLifetimeRemaining(): number {\n    if (!this.#tokenSet?.expiresIn) return -1;\n    const elapsed = (Date.now() - this.#tokenSet.acquiredAt) / 1000;\n    return Math.max(0, this.#tokenSet.expiresIn - elapsed);\n  }\n\n  // ─── Convenience HTTP verbs ─────────────────────────────────────────\n\n  async get<T = unknown>(service: Service, relativeUrl: string, options?: RequestOptions): Promise<T> {\n    return this.invoke<T>(service, HttpMethod.GET, relativeUrl, options);\n  }\n\n  async post<T = unknown>(service: Service, relativeUrl: string, options?: RequestOptions): Promise<T> {\n    return this.invoke<T>(service, HttpMethod.POST, relativeUrl, options);\n  }\n\n  async put<T = unknown>(service: Service, relativeUrl: string, options?: RequestOptions): Promise<T> {\n    return this.invoke<T>(service, HttpMethod.PUT, relativeUrl, options);\n  }\n\n  async delete<T = unknown>(service: Service, relativeUrl: string, options?: RequestOptions): Promise<T> {\n    return this.invoke<T>(service, HttpMethod.DELETE, relativeUrl, options);\n  }\n\n  async patch<T = unknown>(service: Service, relativeUrl: string, options?: RequestOptions): Promise<T> {\n    return this.invoke<T>(service, HttpMethod.PATCH, relativeUrl, options);\n  }\n\n  // ─── Core invoke ────────────────────────────────────────────────────\n\n  /**\n   * Low-level request method. Convenience verbs delegate here.\n   *\n   * When `options.fullResponse` is true, returns SafeguardResponse<T> with status + headers.\n   * Otherwise returns just the parsed response body as T.\n   */\n  async invoke<T = unknown>(\n    service: Service,\n    method: HttpMethod,\n    relativeUrl: string,\n    options?: RequestOptions,\n  ): Promise<T> {\n    if (!this.#connected || !this.#httpClient) {\n      throw new ConfigurationError('Client not connected. Call connect() first.');\n    }\n\n    // Auto-refresh token if needed\n    if (this.#autoRefresh) {\n      await this.#ensureValidToken();\n    }\n\n    const url = buildRequestUrl(this.#host, service, relativeUrl, options?.query, this.#apiVersion);\n    const headers: Record<string, string> = {\n      Authorization: `Bearer ${this.#tokenSet!.accessToken.expose()}`,\n      Accept: 'application/json',\n      ...options?.headers,\n    };\n\n    let body: string | null = null;\n    if (options?.json != null) {\n      body = JSON.stringify(options.json);\n      headers['Content-Type'] = 'application/json';\n    } else if (options?.body != null) {\n      body = options.body as string;\n    }\n\n    const requestOpts: import('./http/types.js').HttpRequestOptions = {\n      url,\n      method,\n      headers,\n      body,\n      timeout: options?.timeout ?? this.#timeout,\n    };\n    if (options?.signal) requestOpts.signal = options.signal;\n\n    const response = await this.#httpClient.request(requestOpts);\n\n    if (response.status >= 400) {\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    const data = response.body ? (JSON.parse(response.body) as T) : (undefined as T);\n\n    if (options?.fullResponse) {\n      return { data, status: response.status, headers: response.headers } as unknown as T;\n    }\n\n    return data;\n  }\n\n  // ─── Private helpers ────────────────────────────────────────────────\n\n  async #ensureValidToken(): Promise<void> {\n    if (!this.#tokenSet) return;\n    if (!this.#tokenSet.expiresIn) return; // can't determine expiry\n\n    const elapsed = Date.now() - this.#tokenSet.acquiredAt;\n    const expiresInMs = this.#tokenSet.expiresIn * 1000;\n\n    if (elapsed + TOKEN_REFRESH_MARGIN_MS < expiresInMs) {\n      return; // token still fresh\n    }\n\n    // Single-flight: if a refresh is already running, all concurrent callers\n    // await the same promise so the auth server only sees one exchange and no\n    // two callers race the storage provider.\n    if (this.#tokenRefreshPromise) {\n      await this.#tokenRefreshPromise;\n      return;\n    }\n\n    this.#tokenRefreshPromise = (async (): Promise<void> => {\n      if (this.#auth.refreshToken) {\n        const refreshed = await this.#auth.refreshToken(this.#host, this.#httpClient!, this.#storage);\n        if (refreshed) {\n          this.#tokenSet = refreshed;\n          return;\n        }\n      }\n      this.#tokenSet = await this.#auth.authenticate(this.#host, this.#httpClient!, this.#storage);\n    })();\n\n    try {\n      await this.#tokenRefreshPromise;\n    } finally {\n      // Always clear the slot — failures must not be cached, otherwise\n      // every subsequent invoke would inherit the same rejection forever.\n      this.#tokenRefreshPromise = undefined;\n    }\n  }\n}\n","/**\n * SSH key formats for private key retrieval.\n */\nexport enum SshKeyFormat {\n  OpenSsh = 'OpenSsh',\n  Ssh2 = 'Ssh2',\n  Putty = 'Putty',\n}\n\n/**\n * An A2A retrievable account as returned by the discovery endpoint.\n */\nexport interface RetrievableAccount {\n  AccountId: number;\n  AssetId: number;\n  AssetName: string;\n  AccountName: string;\n  DomainName: string;\n  AccountType: string;\n  ApiKey: string;\n}\n\n/**\n * Brokered access request types.\n */\nexport enum BrokeredAccessRequestType {\n  Password = 'Password',\n  SshKey = 'SshKey',\n  ApiKey = 'ApiKey',\n  Token = 'Token',\n  RdpFile = 'RdpFile',\n  RemoteDesktop = 'RemoteDesktop',\n  SshSession = 'SshSession',\n}\n\n/**\n * Options for creating a brokered access request.\n */\nexport interface BrokeredAccessRequest {\n  AccessType: BrokeredAccessRequestType;\n  ForUserId?: number;\n  ForUserName?: string;\n  AssetId?: number;\n  AccountId?: number;\n  AccountAssetId?: number;\n  AccountName?: string;\n  AssetName?: string;\n  DomainName?: string;\n}\n\n/**\n * Response from a brokered access request.\n */\nexport interface BrokeredAccessResponse {\n  RequestId: string;\n  AccessToken?: string;\n  [key: string]: unknown;\n}\n","import type { HttpClient } from '../http/types.js';\nimport type { CertificateAuth } from '../auth/certificate.js';\nimport { SecretValue } from '../secret.js';\nimport { ConfigurationError, ApiError } from '../errors.js';\nimport { SshKeyFormat } from './types.js';\nimport type {\n  RetrievableAccount,\n  BrokeredAccessRequest,\n  BrokeredAccessResponse,\n} from './types.js';\n\nexport interface A2AClientOptions {\n  /** Certificate-based auth (A2A always uses client certificates). */\n  auth: CertificateAuth;\n  /** Custom CA certificate (PEM). */\n  ca?: string | Buffer;\n  /** Whether to verify TLS. Default: true. */\n  verify?: boolean;\n  /** API version string (default: 'v4'). */\n  apiVersion?: string;\n}\n\n/**\n * Application-to-Application client for programmatic credential retrieval.\n * Uses client certificate authentication exclusively.\n *\n * Full parity with PySafeguard and SafeguardDotNet A2A clients.\n */\nexport class A2AClient {\n  readonly #host: string;\n  readonly #auth: CertificateAuth;\n  readonly #ca: string | Buffer | undefined;\n  readonly #verify: boolean;\n  readonly #apiVersion: string;\n  #httpClient: HttpClient | undefined;\n\n  constructor(host: string, options: A2AClientOptions) {\n    if (!host) throw new ConfigurationError('A2AClient requires a host');\n    if (!options.auth) throw new ConfigurationError('A2AClient requires a CertificateAuth');\n    this.#host = host;\n    this.#auth = options.auth;\n    this.#ca = options.ca;\n    this.#verify = options.verify !== false;\n    this.#apiVersion = options.apiVersion ?? 'v4';\n  }\n\n  /** The appliance hostname. */\n  get host(): string {\n    return this.#host;\n  }\n\n  /** Custom CA, if set. */\n  get ca(): string | Buffer | undefined {\n    return this.#ca;\n  }\n\n  /** Whether TLS verification is enabled. */\n  get verify(): boolean {\n    return this.#verify;\n  }\n\n  /** The CertificateAuth providing TLS client cert configuration. */\n  get auth(): CertificateAuth {\n    return this.#auth;\n  }\n\n  /**\n   * Sets the HttpClient (must be configured with client cert TLS).\n   */\n  setHttpClient(httpClient: HttpClient): this {\n    this.#httpClient = httpClient;\n    return this;\n  }\n\n  /**\n   * Retrieve a password credential via A2A.\n   * @param apiKey - The API key for the retrievable account\n   */\n  async retrievePassword(apiKey: string): Promise<SecretValue> {\n    const body = await this.#a2aRequest(apiKey, 'GET', 'Credentials', { type: 'Password' });\n    return new SecretValue(body);\n  }\n\n  /**\n   * Retrieve an SSH private key credential via A2A.\n   * @param apiKey - The API key for the retrievable account\n   * @param format - SSH key format (default: OpenSsh)\n   */\n  async retrievePrivateKey(apiKey: string, format?: SshKeyFormat): Promise<SecretValue> {\n    const keyType = format ?? SshKeyFormat.OpenSsh;\n    const body = await this.#a2aRequest(apiKey, 'GET', 'Credentials', {\n      type: 'SshKey',\n      keyFormat: keyType,\n    });\n    return new SecretValue(body);\n  }\n\n  /**\n   * Retrieve an API key secret credential via A2A.\n   * @param apiKey - The API key for the retrievable account\n   */\n  async retrieveApiKeySecret(apiKey: string): Promise<SecretValue> {\n    const body = await this.#a2aRequest(apiKey, 'GET', 'Credentials', { type: 'ApiKey' });\n    return new SecretValue(body);\n  }\n\n  /**\n   * Get the list of retrievable accounts available to this certificate.\n   */\n  async getRetrievableAccounts(): Promise<RetrievableAccount[]> {\n    this.#ensureHttpClient();\n    const response = await this.#httpClient!.request({\n      url: `https://${this.#host}/service/a2a/${this.#apiVersion}/A2ARegistrations`,\n      method: 'GET',\n      headers: {\n        Accept: 'application/json',\n      },\n    });\n\n    if (response.status !== 200) {\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    return JSON.parse(response.body) as RetrievableAccount[];\n  }\n\n  /**\n   * Set a password on a managed account via A2A.\n   * @param apiKey - The API key for the account\n   * @param password - The new password value\n   */\n  async setPassword(apiKey: string, password: string): Promise<void> {\n    this.#ensureHttpClient();\n    const response = await this.#httpClient!.request({\n      url: `https://${this.#host}/service/a2a/${this.#apiVersion}/Credentials?type=Password`,\n      method: 'PUT',\n      headers: {\n        Authorization: `A2A ${apiKey}`,\n        'Content-Type': 'application/json',\n        Accept: 'application/json',\n      },\n      body: JSON.stringify(password),\n    });\n\n    if (response.status !== 200 && response.status !== 204) {\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n  }\n\n  /**\n   * Set a private key on a managed account via A2A.\n   * @param apiKey - The API key for the account\n   * @param key - The private key content\n   * @param passphrase - Optional passphrase for the key\n   * @param format - SSH key format (default: OpenSsh)\n   */\n  async setPrivateKey(\n    apiKey: string,\n    key: string,\n    passphrase?: string,\n    format?: SshKeyFormat,\n  ): Promise<void> {\n    this.#ensureHttpClient();\n    const keyFormat = format ?? SshKeyFormat.OpenSsh;\n    const payload: Record<string, string> = { PrivateKey: key, KeyFormat: keyFormat };\n    if (passphrase) payload['Passphrase'] = passphrase;\n\n    const response = await this.#httpClient!.request({\n      url: `https://${this.#host}/service/a2a/${this.#apiVersion}/Credentials?type=SshKey`,\n      method: 'PUT',\n      headers: {\n        Authorization: `A2A ${apiKey}`,\n        'Content-Type': 'application/json',\n        Accept: 'application/json',\n      },\n      body: JSON.stringify(payload),\n    });\n\n    if (response.status !== 200 && response.status !== 204) {\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n  }\n\n  /**\n   * Submit a brokered access request via A2A.\n   * @param apiKey - The API key for the access request\n   * @param request - The access request details\n   */\n  async brokerAccessRequest(\n    apiKey: string,\n    request: BrokeredAccessRequest,\n  ): Promise<BrokeredAccessResponse> {\n    this.#ensureHttpClient();\n    const response = await this.#httpClient!.request({\n      url: `https://${this.#host}/service/a2a/${this.#apiVersion}/AccessRequests`,\n      method: 'POST',\n      headers: {\n        Authorization: `A2A ${apiKey}`,\n        'Content-Type': 'application/json',\n        Accept: 'application/json',\n      },\n      body: JSON.stringify(request),\n    });\n\n    if (response.status !== 200 && response.status !== 201) {\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    return JSON.parse(response.body) as BrokeredAccessResponse;\n  }\n\n  // ─── Private helpers ────────────────────────────────────────────────\n\n  async #a2aRequest(\n    apiKey: string,\n    method: string,\n    endpoint: string,\n    queryParams?: Record<string, string>,\n  ): Promise<string> {\n    this.#ensureHttpClient();\n    let url = `https://${this.#host}/service/a2a/${this.#apiVersion}/${endpoint}`;\n    if (queryParams) {\n      const params = new URLSearchParams(queryParams);\n      url += `?${params.toString()}`;\n    }\n\n    const response = await this.#httpClient!.request({\n      url,\n      method,\n      headers: {\n        Authorization: `A2A ${apiKey}`,\n        Accept: 'application/json',\n      },\n    });\n\n    if (response.status !== 200) {\n      throw ApiError.fromResponse(response.status, response.body);\n    }\n\n    return response.body;\n  }\n\n  #ensureHttpClient(): void {\n    if (!this.#httpClient) {\n      throw new ConfigurationError(\n        'HttpClient not set. Call setHttpClient() with a client configured for mTLS.',\n      );\n    }\n  }\n}\n\nexport { SshKeyFormat, BrokeredAccessRequestType } from './types.js';\nexport type { RetrievableAccount, BrokeredAccessRequest, BrokeredAccessResponse } from './types.js';\n"],"mappings":"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"}