@mcp-abap-adt/connection 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ import type { ICertificateMaterial, ICertificateMaterialLoader, ISapConfig } from '@mcp-abap-adt/interfaces';
2
+ export declare class FileCertificateMaterialLoader implements ICertificateMaterialLoader {
3
+ load(config: ISapConfig): Promise<ICertificateMaterial>;
4
+ }
5
+ //# sourceMappingURL=FileCertificateMaterialLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileCertificateMaterialLoader.d.ts","sourceRoot":"","sources":["../../src/auth/FileCertificateMaterialLoader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,UAAU,EACX,MAAM,0BAA0B,CAAC;AAElC,qBAAa,6BACX,YAAW,0BAA0B;IAE/B,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAyB9D"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileCertificateMaterialLoader = void 0;
4
+ const promises_1 = require("node:fs/promises");
5
+ class FileCertificateMaterialLoader {
6
+ async load(config) {
7
+ const hasPem = !!(config.certPath || config.certKeyPath); // any PEM-style field present
8
+ const hasPfx = !!config.certPfxPath;
9
+ if (hasPem && hasPfx) {
10
+ throw new Error('Certificate auth: provide either PEM (certPath+certKeyPath) OR certPfxPath, not both.');
11
+ }
12
+ if (hasPfx) {
13
+ return {
14
+ pfx: await (0, promises_1.readFile)(config.certPfxPath),
15
+ passphrase: config.certPassphrase,
16
+ };
17
+ }
18
+ if (config.certPath && config.certKeyPath) {
19
+ return {
20
+ cert: await (0, promises_1.readFile)(config.certPath),
21
+ key: await (0, promises_1.readFile)(config.certKeyPath),
22
+ passphrase: config.certPassphrase,
23
+ };
24
+ }
25
+ throw new Error('Certificate auth requires certPfxPath OR (certPath AND certKeyPath).');
26
+ }
27
+ }
28
+ exports.FileCertificateMaterialLoader = FileCertificateMaterialLoader;
@@ -0,0 +1,3 @@
1
+ /** Thin, lazily-loaded wrapper over the optional `kerberos` native package. */
2
+ export declare function generateSpnegoToken(spn: string): Promise<string>;
3
+ //# sourceMappingURL=kerberosSpnego.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kerberosSpnego.d.ts","sourceRoot":"","sources":["../../src/auth/kerberosSpnego.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBtE"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateSpnegoToken = generateSpnegoToken;
37
+ /** Thin, lazily-loaded wrapper over the optional `kerberos` native package. */
38
+ async function generateSpnegoToken(spn) {
39
+ // optional peer dep; typed as any because the module/types may be absent
40
+ let kerberos;
41
+ try {
42
+ // @ts-expect-error optional peer dependency — module may be absent at build time (TS2307)
43
+ kerberos = await Promise.resolve().then(() => __importStar(require('kerberos')));
44
+ }
45
+ catch {
46
+ throw new Error('Kerberos authentication requires the optional "kerberos" package. ' +
47
+ 'Install it (needs GSSAPI dev libs on Linux / build tools on Windows): npm i kerberos');
48
+ }
49
+ const client = await kerberos.initializeClient(spn, {});
50
+ await client.step('');
51
+ const token = client.response;
52
+ if (!token) {
53
+ throw new Error('Kerberos: no SPNEGO token produced (no TGT? run kinit, or check SPN).');
54
+ }
55
+ return token;
56
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"sapConfig.d.ts","sourceRoot":"","sources":["../../src/config/sapConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;AAC/C,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC;AAEnC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAuB7D"}
1
+ {"version":3,"file":"sapConfig.d.ts","sourceRoot":"","sources":["../../src/config/sapConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;AAC/C,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC;AAEnC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA4B7D"}
@@ -22,5 +22,10 @@ function sapConfigSignature(config) {
22
22
  jwtToken: jwtTokenPreview,
23
23
  refreshToken: refreshTokenPreview,
24
24
  sessionCookies: sessionCookiesPreview,
25
+ certPath: config.certPath ?? null,
26
+ certKeyPath: config.certKeyPath ?? null,
27
+ certPfxPath: config.certPfxPath ?? null,
28
+ certPassphrase: config.certPassphrase ? 'set' : null,
29
+ kerberosSpn: config.kerberosSpn ?? null,
25
30
  });
26
31
  }
@@ -81,8 +81,21 @@ declare abstract class AbstractAbapConnection implements AbapConnection {
81
81
  protected getCookies(): string | null;
82
82
  protected setInitialCookies(cookies: string): void;
83
83
  private updateCookiesFromResponse;
84
+ /**
85
+ * Subclasses override to inject extra https.Agent options (e.g. mTLS cert/key/pfx).
86
+ * The returned options are merged with the base options (rejectUnauthorized).
87
+ */
88
+ protected getHttpsAgentOptions(): import('node:https').AgentOptions;
84
89
  private getAxiosInstance;
85
90
  private ensureFreshCsrfToken;
91
+ /**
92
+ * Clear SAP-side session state when SAP rejects the cached CSRF token + session
93
+ * cookies (HTTP 401 on a mutation while a cached token exists). This forces the
94
+ * next request path to fetch a fresh token and a fresh SAP_SESSIONID cookie.
95
+ *
96
+ * Distinct from reset(): this leaves the axios instance and interceptors in place.
97
+ */
98
+ private invalidateSession;
86
99
  private shouldRetryCsrf;
87
100
  }
88
101
  export { AbstractAbapConnection };
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/AbstractAbapConnection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAkB,MAAM,0BAA0B,CAAC;AAM7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,uBAAe,sBAAuB,YAAW,cAAc;IAW3D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAX3C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,eAAe,CAAU;IAEjC,SAAS,aACU,MAAM,EAAE,SAAS,EACf,MAAM,EAAE,OAAO,GAAG,IAAI,EACzC,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE;IAqBzC;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAUpD;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,UAAU;IAI1C;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKrC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,SAAS,IAAI,SAAS;IAItB,KAAK,IAAI,IAAI;IAYP,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAevD;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE3B,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EACnC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA4P9B,SAAS,CAAC,QAAQ,CAAC,wBAAwB,IAAI,MAAM;IAErD;;;OAGG;cACa,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAgC,EAC5C,UAAU,GAAE,MAAgC,GAC3C,OAAO,CAAC,MAAM,CAAC;IA2ClB;;OAEG;YACW,0BAA0B;IAsKxC;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIlD;;OAEG;IACH,SAAS,CAAC,UAAU,IAAI,MAAM,GAAG,IAAI;IAIrC,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlD,OAAO,CAAC,yBAAyB;IAkEjC,OAAO,CAAC,gBAAgB;YAqBV,oBAAoB;IAiClC,OAAO,CAAC,eAAe;CA+BxB;AAGD,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"AbstractAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/AbstractAbapConnection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAkB,MAAM,0BAA0B,CAAC;AAM7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,uBAAe,sBAAuB,YAAW,cAAc;IAW3D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAX3C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,eAAe,CAAU;IAEjC,SAAS,aACU,MAAM,EAAE,SAAS,EACf,MAAM,EAAE,OAAO,GAAG,IAAI,EACzC,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE;IAqBzC;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAUpD;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,UAAU;IAI1C;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKrC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,SAAS,IAAI,SAAS;IAItB,KAAK,IAAI,IAAI;IAYP,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAevD;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE3B,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EACnC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA+R9B,SAAS,CAAC,QAAQ,CAAC,wBAAwB,IAAI,MAAM;IAErD;;;OAGG;cACa,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAgC,EAC5C,UAAU,GAAE,MAAgC,GAC3C,OAAO,CAAC,MAAM,CAAC;IA2ClB;;OAEG;YACW,0BAA0B;IAsKxC;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIlD;;OAEG;IACH,SAAS,CAAC,UAAU,IAAI,MAAM,GAAG,IAAI;IAIrC,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlD,OAAO,CAAC,yBAAyB;IAkEjC;;;OAGG;IACH,SAAS,CAAC,oBAAoB,IAAI,OAAO,YAAY,EAAE,YAAY;IAInE,OAAO,CAAC,gBAAgB;YAsBV,oBAAoB;IAiClC;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;CA+BxB;AAGD,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -263,22 +263,51 @@ class AbstractAbapConnection {
263
263
  else {
264
264
  this.logger?.error(errorDetails.message, errorDetails);
265
265
  }
266
- // Retry logic for CSRF token errors (403 with CSRF message)
267
- if (this.shouldRetryCsrf(error)) {
268
- this.logger?.debug('CSRF token validation failed, fetching new token and retrying request', {
266
+ // Detect the "login-form 401" pattern: SAP returned 401 for a mutation while
267
+ // we have a cached CSRF token. The token and its bound SAP session must be
268
+ // discarded before the retry. Basic auth only JWT/SAML lifecycles are
269
+ // managed elsewhere.
270
+ const isCachedTokenStale = error instanceof axios_1.AxiosError &&
271
+ this.config.authType === 'basic' &&
272
+ (normalizedMethod === 'POST' ||
273
+ normalizedMethod === 'PUT' ||
274
+ normalizedMethod === 'DELETE') &&
275
+ error.response?.status === 401 &&
276
+ this.getCsrfToken() !== null;
277
+ // Retry logic for CSRF token errors (403 with CSRF message) and the
278
+ // login-form 401 pattern.
279
+ if (this.shouldRetryCsrf(error) || isCachedTokenStale) {
280
+ this.logger?.debug(isCachedTokenStale
281
+ ? 'Stale CSRF token / SAP session — invalidating and retrying'
282
+ : 'CSRF token validation failed, fetching new token and retrying request', {
269
283
  url: requestUrl,
270
284
  method: normalizedMethod,
271
285
  });
272
- this.csrfToken = await this.fetchCsrfToken(requestUrl, 5, 2000);
273
- if (this.csrfToken) {
274
- requestHeaders['x-csrf-token'] = this.csrfToken;
286
+ if (isCachedTokenStale) {
287
+ this.invalidateSession();
288
+ delete requestHeaders.Cookie;
289
+ delete requestHeaders.cookie;
275
290
  }
276
- if (this.cookies) {
277
- requestHeaders.Cookie = this.cookies;
291
+ try {
292
+ this.setCsrfToken(await this.fetchCsrfToken(requestUrl, 5, 2000));
293
+ const refreshedToken = this.getCsrfToken();
294
+ if (refreshedToken) {
295
+ requestHeaders['x-csrf-token'] = refreshedToken;
296
+ }
297
+ const refreshedCookies = this.getCookies();
298
+ if (refreshedCookies) {
299
+ requestHeaders.Cookie = refreshedCookies;
300
+ }
301
+ const retryResponse = await this.getAxiosInstance()(requestConfig);
302
+ this.updateCookiesFromResponse(retryResponse.headers);
303
+ return retryResponse;
304
+ }
305
+ catch (retryError) {
306
+ this.logger?.debug(`CSRF retry failed; rethrowing original error: ${retryError instanceof Error
307
+ ? retryError.message
308
+ : String(retryError)}`);
309
+ throw error;
278
310
  }
279
- const retryResponse = await this.getAxiosInstance()(requestConfig);
280
- this.updateCookiesFromResponse(retryResponse.headers);
281
- return retryResponse;
282
311
  }
283
312
  // Retry logic for 401 errors on GET requests (authentication issue - need cookies)
284
313
  // Only for basic auth - JWT auth will be handled by refresh logic below
@@ -548,6 +577,13 @@ class AbstractAbapConnection {
548
577
  this.cookies = combined;
549
578
  this.logger?.debug(`[DEBUG] BaseAbapConnection - Updated cookies from response (first 100 chars): ${this.cookies.substring(0, 100)}...`);
550
579
  }
580
+ /**
581
+ * Subclasses override to inject extra https.Agent options (e.g. mTLS cert/key/pfx).
582
+ * The returned options are merged with the base options (rejectUnauthorized).
583
+ */
584
+ getHttpsAgentOptions() {
585
+ return {};
586
+ }
551
587
  getAxiosInstance() {
552
588
  if (!this.axiosInstance) {
553
589
  const rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED === '1' ||
@@ -557,6 +593,7 @@ class AbstractAbapConnection {
557
593
  this.axiosInstance = axios_1.default.create({
558
594
  httpsAgent: new node_https_1.Agent({
559
595
  rejectUnauthorized,
596
+ ...this.getHttpsAgentOptions(),
560
597
  }),
561
598
  });
562
599
  }
@@ -585,6 +622,18 @@ class AbstractAbapConnection {
585
622
  throw error;
586
623
  }
587
624
  }
625
+ /**
626
+ * Clear SAP-side session state when SAP rejects the cached CSRF token + session
627
+ * cookies (HTTP 401 on a mutation while a cached token exists). This forces the
628
+ * next request path to fetch a fresh token and a fresh SAP_SESSIONID cookie.
629
+ *
630
+ * Distinct from reset(): this leaves the axios instance and interceptors in place.
631
+ */
632
+ invalidateSession() {
633
+ this.setCsrfToken(null);
634
+ this.cookies = null;
635
+ this.cookieStore.clear();
636
+ }
588
637
  shouldRetryCsrf(error) {
589
638
  if (!(error instanceof axios_1.AxiosError)) {
590
639
  return false;
@@ -0,0 +1,21 @@
1
+ import type { AgentOptions } from 'node:https';
2
+ import type { ICertificateMaterialLoader } from '@mcp-abap-adt/interfaces';
3
+ import type { SapConfig } from '../config/sapConfig.js';
4
+ import type { ILogger } from '../logger.js';
5
+ import { AbstractAbapConnection } from './AbstractAbapConnection.js';
6
+ /** Client-certificate (mTLS) authentication. Credential lives on the TLS agent. */
7
+ export declare class CertificateAbapConnection extends AbstractAbapConnection {
8
+ private loader;
9
+ private material;
10
+ constructor(config: SapConfig, logger?: ILogger | null, sessionId?: string, loader?: ICertificateMaterialLoader);
11
+ private static validateConfig;
12
+ protected ensureMaterial(): Promise<void>;
13
+ /**
14
+ * Loads certificate material and primes the session. MUST be called before the first
15
+ * request — the TLS agent is built lazily and needs the client cert present.
16
+ */
17
+ connect(): Promise<void>;
18
+ protected getHttpsAgentOptions(): AgentOptions;
19
+ protected buildAuthorizationHeader(): string;
20
+ }
21
+ //# sourceMappingURL=CertificateAbapConnection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CertificateAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/CertificateAbapConnection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAEV,0BAA0B,EAC3B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,mFAAmF;AACnF,qBAAa,yBAA0B,SAAQ,sBAAsB;IACnE,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,QAAQ,CAAqC;gBAGnD,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,0BAA0B;IAOrC,OAAO,CAAC,MAAM,CAAC,cAAc;cAyBb,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/C;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B,SAAS,CAAC,oBAAoB,IAAI,YAAY;IAU9C,SAAS,CAAC,wBAAwB,IAAI,MAAM;CAG7C"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CertificateAbapConnection = void 0;
4
+ const axios_1 = require("axios");
5
+ const FileCertificateMaterialLoader_js_1 = require("../auth/FileCertificateMaterialLoader.js");
6
+ const AbstractAbapConnection_js_1 = require("./AbstractAbapConnection.js");
7
+ /** Client-certificate (mTLS) authentication. Credential lives on the TLS agent. */
8
+ class CertificateAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnection {
9
+ loader;
10
+ material = null;
11
+ constructor(config, logger, sessionId, loader) {
12
+ CertificateAbapConnection.validateConfig(config);
13
+ super(config, logger || null, sessionId);
14
+ this.loader = loader ?? new FileCertificateMaterialLoader_js_1.FileCertificateMaterialLoader();
15
+ }
16
+ static validateConfig(config) {
17
+ if (config.authType !== 'certificate') {
18
+ throw new Error(`Certificate connection expects authType "certificate", got "${config.authType}"`);
19
+ }
20
+ if (config.connectionType === 'rfc') {
21
+ throw new Error('Certificate auth is not supported with connectionType "rfc".');
22
+ }
23
+ const hasPem = !!(config.certPath && config.certKeyPath); // complete PEM pair present
24
+ const hasPfx = !!config.certPfxPath;
25
+ if (!hasPem && !hasPfx) {
26
+ throw new Error('Certificate auth requires certPfxPath OR (certPath AND certKeyPath).');
27
+ }
28
+ if ((config.certPath || config.certKeyPath) && config.certPfxPath) {
29
+ throw new Error('Certificate auth: provide either PEM pair OR PFX, not both.');
30
+ }
31
+ }
32
+ async ensureMaterial() {
33
+ if (!this.material) {
34
+ this.material = await this.loader.load(this.getConfig());
35
+ }
36
+ }
37
+ /**
38
+ * Loads certificate material and primes the session. MUST be called before the first
39
+ * request — the TLS agent is built lazily and needs the client cert present.
40
+ */
41
+ async connect() {
42
+ await this.ensureMaterial();
43
+ const baseUrl = await this.getBaseUrl();
44
+ const discoveryUrl = `${baseUrl}/sap/bc/adt/discovery`;
45
+ try {
46
+ const token = await this.fetchCsrfToken(discoveryUrl, 3, 1000);
47
+ this.setCsrfToken(token);
48
+ }
49
+ catch (error) {
50
+ this.logger?.warn(`[WARN] CertificateAbapConnection - connect deferred: ${error instanceof Error ? error.message : String(error)}`);
51
+ if (error instanceof axios_1.AxiosError && error.response?.headers) {
52
+ if (this.getCookies()) {
53
+ this.logger?.debug(`[DEBUG] CertificateAbapConnection - Cookies extracted from error response during connect (first 100 chars): ${this.getCookies()?.substring(0, 100)}...`);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ getHttpsAgentOptions() {
59
+ if (!this.material) {
60
+ throw new Error('CertificateAbapConnection: certificate material not loaded. Call connect() before making requests.');
61
+ }
62
+ const { cert, key, pfx, passphrase } = this.material;
63
+ return { cert, key, pfx, passphrase };
64
+ }
65
+ buildAuthorizationHeader() {
66
+ return '';
67
+ }
68
+ }
69
+ exports.CertificateAbapConnection = CertificateAbapConnection;
@@ -0,0 +1,20 @@
1
+ import type { SapConfig } from '../config/sapConfig.js';
2
+ import type { ILogger } from '../logger.js';
3
+ import { AbstractAbapConnection } from './AbstractAbapConnection.js';
4
+ /** Kerberos / SPNEGO single-leg auth: send Negotiate token, reuse the resulting SAP session cookie. */
5
+ export declare class KerberosAbapConnection extends AbstractAbapConnection {
6
+ private spn;
7
+ private currentToken;
8
+ constructor(config: SapConfig, logger?: ILogger | null, sessionId?: string);
9
+ private static validateConfig;
10
+ /** Generate the SPNEGO token once (single-leg). */
11
+ protected ensureToken(): Promise<void>;
12
+ /**
13
+ * Generates the SPNEGO token and primes the session. MUST be called before the first
14
+ * request — the first request carries the Negotiate header; SAP then issues a session
15
+ * cookie which is reused for subsequent requests.
16
+ */
17
+ connect(): Promise<void>;
18
+ protected buildAuthorizationHeader(): string;
19
+ }
20
+ //# sourceMappingURL=KerberosAbapConnection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KerberosAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/KerberosAbapConnection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,uGAAuG;AACvG,qBAAa,sBAAuB,SAAQ,sBAAsB;IAChE,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,YAAY,CAAM;gBAEd,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM;IAQ1E,OAAO,CAAC,MAAM,CAAC,cAAc;IAa7B,mDAAmD;cACnC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5C;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B9B,SAAS,CAAC,wBAAwB,IAAI,MAAM;CAS7C"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KerberosAbapConnection = void 0;
4
+ const axios_1 = require("axios");
5
+ const kerberosSpnego_js_1 = require("../auth/kerberosSpnego.js");
6
+ const AbstractAbapConnection_js_1 = require("./AbstractAbapConnection.js");
7
+ /** Kerberos / SPNEGO single-leg auth: send Negotiate token, reuse the resulting SAP session cookie. */
8
+ class KerberosAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnection {
9
+ spn;
10
+ currentToken = '';
11
+ constructor(config, logger, sessionId) {
12
+ KerberosAbapConnection.validateConfig(config);
13
+ super(config, logger || null, sessionId);
14
+ this.spn =
15
+ config.kerberosSpn ??
16
+ `${config.kerberosService ?? 'HTTP'}@${new URL(config.url).hostname}`;
17
+ }
18
+ static validateConfig(config) {
19
+ if (config.authType !== 'kerberos') {
20
+ throw new Error(`Kerberos connection expects authType "kerberos", got "${config.authType}"`);
21
+ }
22
+ if (config.connectionType === 'rfc') {
23
+ throw new Error('Kerberos auth is not supported with connectionType "rfc".');
24
+ }
25
+ }
26
+ /** Generate the SPNEGO token once (single-leg). */
27
+ async ensureToken() {
28
+ if (!this.currentToken)
29
+ this.currentToken = await (0, kerberosSpnego_js_1.generateSpnegoToken)(this.spn);
30
+ }
31
+ /**
32
+ * Generates the SPNEGO token and primes the session. MUST be called before the first
33
+ * request — the first request carries the Negotiate header; SAP then issues a session
34
+ * cookie which is reused for subsequent requests.
35
+ */
36
+ async connect() {
37
+ await this.ensureToken();
38
+ const baseUrl = await this.getBaseUrl();
39
+ const discoveryUrl = `${baseUrl}/sap/bc/adt/discovery`;
40
+ this.logger?.debug(`[DEBUG] KerberosAbapConnection - Connecting to SAP system: ${discoveryUrl}`);
41
+ try {
42
+ const token = await this.fetchCsrfToken(discoveryUrl, 3, 1000);
43
+ this.setCsrfToken(token);
44
+ }
45
+ catch (error) {
46
+ this.logger?.warn(`[WARN] KerberosAbapConnection - connect deferred: ${error instanceof Error ? error.message : String(error)}`);
47
+ if (error instanceof axios_1.AxiosError &&
48
+ error.response?.headers &&
49
+ this.getCookies()) {
50
+ this.logger?.debug('[DEBUG] KerberosAbapConnection - cookies captured from error response during connect');
51
+ }
52
+ }
53
+ }
54
+ buildAuthorizationHeader() {
55
+ if (this.getCookies())
56
+ return ''; // cookie carries auth after first round-trip
57
+ if (!this.currentToken) {
58
+ throw new Error('KerberosAbapConnection: SPNEGO token not yet available. Call connect() before making requests.');
59
+ }
60
+ return `Negotiate ${this.currentToken}`;
61
+ }
62
+ }
63
+ exports.KerberosAbapConnection = KerberosAbapConnection;
@@ -1,8 +1,9 @@
1
- import type { ITokenRefresher } from '@mcp-abap-adt/interfaces';
1
+ import type { ICertificateMaterialLoader, ITokenRefresher } from '@mcp-abap-adt/interfaces';
2
2
  import type { SapConfig } from '../config/sapConfig.js';
3
3
  import type { ILogger } from '../logger.js';
4
4
  import type { AbapConnection } from './AbapConnection.js';
5
5
  export declare function createAbapConnection(config: SapConfig, logger?: ILogger | null, sessionId?: string, tokenRefresher?: ITokenRefresher, options?: {
6
6
  skipSessionType?: boolean;
7
+ certLoader?: ICertificateMaterialLoader;
7
8
  }): AbapConnection;
8
9
  //# sourceMappingURL=connectionFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connectionFactory.d.ts","sourceRoot":"","sources":["../../src/connection/connectionFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAM1D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,eAAe,EAChC,OAAO,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GACtC,cAAc,CAkBhB"}
1
+ {"version":3,"file":"connectionFactory.d.ts","sourceRoot":"","sources":["../../src/connection/connectionFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAQ1D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,eAAe,EAChC,OAAO,CAAC,EAAE;IACR,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,0BAA0B,CAAC;CACzC,GACA,cAAc,CAgChB"}
@@ -2,12 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createAbapConnection = createAbapConnection;
4
4
  const BaseAbapConnection_js_1 = require("./BaseAbapConnection.js");
5
+ const CertificateAbapConnection_js_1 = require("./CertificateAbapConnection.js");
5
6
  const JwtAbapConnection_js_1 = require("./JwtAbapConnection.js");
7
+ const KerberosAbapConnection_js_1 = require("./KerberosAbapConnection.js");
6
8
  const RfcAbapConnection_js_1 = require("./RfcAbapConnection.js");
7
9
  const SamlAbapConnection_js_1 = require("./SamlAbapConnection.js");
8
10
  function createAbapConnection(config, logger, sessionId, tokenRefresher, options) {
9
11
  // RFC connection type takes priority over auth type
10
12
  if (config.connectionType === 'rfc') {
13
+ if (config.authType === 'certificate' || config.authType === 'kerberos') {
14
+ throw new Error(`authType "${config.authType}" is not supported with connectionType "rfc".`);
15
+ }
11
16
  return new RfcAbapConnection_js_1.RfcAbapConnection(config, logger);
12
17
  }
13
18
  switch (config.authType) {
@@ -17,6 +22,10 @@ function createAbapConnection(config, logger, sessionId, tokenRefresher, options
17
22
  return new JwtAbapConnection_js_1.JwtAbapConnection(config, logger, sessionId, tokenRefresher);
18
23
  case 'saml':
19
24
  return new SamlAbapConnection_js_1.SamlAbapConnection(config, logger, sessionId, options);
25
+ case 'certificate':
26
+ return new CertificateAbapConnection_js_1.CertificateAbapConnection(config, logger, sessionId, options?.certLoader);
27
+ case 'kerberos':
28
+ return new KerberosAbapConnection_js_1.KerberosAbapConnection(config, logger, sessionId);
20
29
  default:
21
30
  throw new Error(`Unsupported SAP authentication type: ${config.authType}`);
22
31
  }
package/dist/index.d.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  export type { IWebSocketCloseInfo, IWebSocketConnectOptions, IWebSocketMessageEnvelope, IWebSocketMessageHandler, IWebSocketTransport, } from '@mcp-abap-adt/interfaces';
2
+ export { FileCertificateMaterialLoader } from './auth/FileCertificateMaterialLoader.js';
2
3
  export type { SapAuthType, SapConfig, SapConnectionType, } from './config/sapConfig.js';
3
4
  export { sapConfigSignature } from './config/sapConfig.js';
4
5
  export type { AbapConnection, AbapRequestOptions, } from './connection/AbapConnection.js';
5
6
  export { BaseAbapConnection, BaseAbapConnection as OnPremAbapConnection, } from './connection/BaseAbapConnection.js';
7
+ export { CertificateAbapConnection } from './connection/CertificateAbapConnection.js';
6
8
  export { createAbapConnection } from './connection/connectionFactory.js';
7
9
  export { CSRF_CONFIG, CSRF_ERROR_MESSAGES } from './connection/csrfConfig.js';
8
10
  export { GenericWebSocketTransport, type IWebSocketFactory, type IWebSocketLike, } from './connection/GenericWebSocketTransport.js';
9
11
  export { JwtAbapConnection, JwtAbapConnection as CloudAbapConnection, } from './connection/JwtAbapConnection.js';
12
+ export { KerberosAbapConnection } from './connection/KerberosAbapConnection.js';
10
13
  export { RfcAbapConnection } from './connection/RfcAbapConnection.js';
11
14
  export { SamlAbapConnection } from './connection/SamlAbapConnection.js';
12
15
  export type { ILogger } from './logger.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,YAAY,EACV,cAAc,EACd,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,IAAI,oBAAoB,GAC3C,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EACL,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,IAAI,mBAAmB,GACzC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AACxF,YAAY,EACV,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,YAAY,EACV,cAAc,EACd,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,IAAI,oBAAoB,GAC3C,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAEtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EACL,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,IAAI,mBAAmB,GACzC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  // Types - re-exported from interfaces package with backward compatibility aliases
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.getTimeoutConfig = exports.getTimeout = exports.SamlAbapConnection = exports.RfcAbapConnection = exports.CloudAbapConnection = exports.JwtAbapConnection = exports.GenericWebSocketTransport = exports.CSRF_ERROR_MESSAGES = exports.CSRF_CONFIG = exports.createAbapConnection = exports.OnPremAbapConnection = exports.BaseAbapConnection = exports.sapConfigSignature = void 0;
4
+ exports.getTimeoutConfig = exports.getTimeout = exports.SamlAbapConnection = exports.RfcAbapConnection = exports.KerberosAbapConnection = exports.CloudAbapConnection = exports.JwtAbapConnection = exports.GenericWebSocketTransport = exports.CSRF_ERROR_MESSAGES = exports.CSRF_CONFIG = exports.createAbapConnection = exports.CertificateAbapConnection = exports.OnPremAbapConnection = exports.BaseAbapConnection = exports.sapConfigSignature = exports.FileCertificateMaterialLoader = void 0;
5
+ var FileCertificateMaterialLoader_js_1 = require("./auth/FileCertificateMaterialLoader.js");
6
+ Object.defineProperty(exports, "FileCertificateMaterialLoader", { enumerable: true, get: function () { return FileCertificateMaterialLoader_js_1.FileCertificateMaterialLoader; } });
5
7
  // Config utilities
6
8
  var sapConfig_js_1 = require("./config/sapConfig.js");
7
9
  Object.defineProperty(exports, "sapConfigSignature", { enumerable: true, get: function () { return sapConfig_js_1.sapConfigSignature; } });
@@ -10,6 +12,8 @@ Object.defineProperty(exports, "sapConfigSignature", { enumerable: true, get: fu
10
12
  var BaseAbapConnection_js_1 = require("./connection/BaseAbapConnection.js");
11
13
  Object.defineProperty(exports, "BaseAbapConnection", { enumerable: true, get: function () { return BaseAbapConnection_js_1.BaseAbapConnection; } });
12
14
  Object.defineProperty(exports, "OnPremAbapConnection", { enumerable: true, get: function () { return BaseAbapConnection_js_1.BaseAbapConnection; } });
15
+ var CertificateAbapConnection_js_1 = require("./connection/CertificateAbapConnection.js");
16
+ Object.defineProperty(exports, "CertificateAbapConnection", { enumerable: true, get: function () { return CertificateAbapConnection_js_1.CertificateAbapConnection; } });
13
17
  // Factory
14
18
  var connectionFactory_js_1 = require("./connection/connectionFactory.js");
15
19
  Object.defineProperty(exports, "createAbapConnection", { enumerable: true, get: function () { return connectionFactory_js_1.createAbapConnection; } });
@@ -22,6 +26,8 @@ Object.defineProperty(exports, "GenericWebSocketTransport", { enumerable: true,
22
26
  var JwtAbapConnection_js_1 = require("./connection/JwtAbapConnection.js");
23
27
  Object.defineProperty(exports, "JwtAbapConnection", { enumerable: true, get: function () { return JwtAbapConnection_js_1.JwtAbapConnection; } });
24
28
  Object.defineProperty(exports, "CloudAbapConnection", { enumerable: true, get: function () { return JwtAbapConnection_js_1.JwtAbapConnection; } });
29
+ var KerberosAbapConnection_js_1 = require("./connection/KerberosAbapConnection.js");
30
+ Object.defineProperty(exports, "KerberosAbapConnection", { enumerable: true, get: function () { return KerberosAbapConnection_js_1.KerberosAbapConnection; } });
25
31
  var RfcAbapConnection_js_1 = require("./connection/RfcAbapConnection.js");
26
32
  Object.defineProperty(exports, "RfcAbapConnection", { enumerable: true, get: function () { return RfcAbapConnection_js_1.RfcAbapConnection; } });
27
33
  var SamlAbapConnection_js_1 = require("./connection/SamlAbapConnection.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/connection",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "ABAP connection layer for MCP ABAP ADT server",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -46,14 +46,15 @@
46
46
  "node": ">=18.0.0"
47
47
  },
48
48
  "dependencies": {
49
- "@mcp-abap-adt/interfaces": "^7.0.0",
49
+ "@mcp-abap-adt/interfaces": "^7.2.0",
50
50
  "axios": "^1.13.5",
51
51
  "commander": "^14.0.3",
52
52
  "express": "^5.1.0",
53
53
  "open": "^11.0.0"
54
54
  },
55
55
  "optionalDependencies": {
56
- "@mcp-abap-adt/sap-rfc-lite": "^0.1.0"
56
+ "@mcp-abap-adt/sap-rfc-lite": "^0.1.0",
57
+ "kerberos": "^2.1.0"
57
58
  },
58
59
  "devDependencies": {
59
60
  "@biomejs/biome": "^2.3.14",