@mcp-abap-adt/connection 1.10.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +758 -0
- package/README.md +42 -11
- package/dist/__tests__/helpers/session.d.ts +15 -0
- package/dist/__tests__/helpers/session.d.ts.map +1 -0
- package/dist/__tests__/helpers/session.js +19 -0
- package/dist/auth/ntlm.d.ts +15 -0
- package/dist/auth/ntlm.d.ts.map +1 -1
- package/dist/auth/ntlm.js +38 -0
- package/dist/connection/AbstractAbapConnection.d.ts +163 -11
- package/dist/connection/AbstractAbapConnection.d.ts.map +1 -1
- package/dist/connection/AbstractAbapConnection.js +351 -14
- package/dist/connection/BaseAbapConnection.d.ts +5 -1
- package/dist/connection/BaseAbapConnection.d.ts.map +1 -1
- package/dist/connection/BaseAbapConnection.js +11 -1
- package/dist/connection/CertificateAbapConnection.d.ts +5 -1
- package/dist/connection/CertificateAbapConnection.d.ts.map +1 -1
- package/dist/connection/CertificateAbapConnection.js +11 -1
- package/dist/connection/JwtAbapConnection.d.ts +3 -2
- package/dist/connection/JwtAbapConnection.d.ts.map +1 -1
- package/dist/connection/JwtAbapConnection.js +19 -8
- package/dist/connection/KerberosAbapConnection.d.ts +5 -1
- package/dist/connection/KerberosAbapConnection.d.ts.map +1 -1
- package/dist/connection/KerberosAbapConnection.js +54 -3
- package/dist/connection/SamlAbapConnection.d.ts +5 -1
- package/dist/connection/SamlAbapConnection.d.ts.map +1 -1
- package/dist/connection/SamlAbapConnection.js +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/session/SessionLifecycle.d.ts +2 -9
- package/dist/session/SessionLifecycle.d.ts.map +1 -1
- package/dist/session/SessionLifecycle.js +8 -8
- package/docs/INDEX.md +106 -0
- package/docs/INSTALLATION.md +304 -0
- package/docs/JWT_AUTH_TOOLS.md +142 -0
- package/docs/MIGRATION-2.0.md +125 -0
- package/docs/SCOPE.md +44 -0
- package/docs/STATEFUL_SESSION_GUIDE.md +121 -0
- package/docs/USAGE.md +749 -0
- package/examples/README.md +112 -0
- package/examples/basic-connection.js +55 -0
- package/examples/jwt-with-token-refresh.js +87 -0
- package/examples/saml-connection.js +52 -0
- package/examples/websocket-transport.js +87 -0
- package/package.json +11 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the `@mcp-abap-adt/connection` package will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.0.0] - 2026-07-29
|
|
11
|
+
|
|
12
|
+
The connection owns its session now, and says so. Before this release a stateful
|
|
13
|
+
ADT session could be replaced underneath a caller holding a lock — silently,
|
|
14
|
+
under an unchanged `sap-adt-connection-id`, with no way for either side to
|
|
15
|
+
notice. That is what orphans an edit lock and leaves an object inactive and
|
|
16
|
+
locked with nobody able to say whether the connector changed or the session
|
|
17
|
+
broke. Migration guide: [`docs/MIGRATION-2.0.md`](docs/MIGRATION-2.0.md).
|
|
18
|
+
|
|
19
|
+
### Changed — BREAKING
|
|
20
|
+
- **`connect()` is mandatory, and it rejects when it fails.** `makeAdtRequest()` now refuses with `ADT_NOT_CONNECTED` unless the connection was explicitly connected, and `connect()` no longer swallows a failed establishment: it used to log a warning, resolve anyway and defer establishment to the first request, which was coherent only while that lazy path existed. Removing it means a swallowed failure would leave a connection reporting success while holding nothing. A caller that never checked `connect()` now fails at startup rather than at the first request — the better failure, but a new one.
|
|
21
|
+
- **Consumers must call `connect()` before the first request.** Requests are also refused after `disconnect()` and after `reset()`, until the next `connect()`. An in-flight request is not cut off: a teardown drains before it clears anything.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- **`disconnect(): Promise<ITeardownReport>`.** Resolves rather than throws, and reports what the teardown could not finish: `abandonedWindows` names the lock windows still open when the bounded wait gave up, `releasePending` says a transport release is still outstanding. A caller learns which locks it must clean up by hand instead of discovering them on the next developer's screen.
|
|
25
|
+
- **`isConnected()` and `getSessionIdentity()`.** The session is observable now: whether a caller may work, and which ABAP session it would work over. The identity is derived from the `SAP_SESSIONID*` cookies and deliberately excludes `sap-XSRF_*`, which rotates on a token refresh *within* one session — folding it in would report an ordinary refresh as a new session.
|
|
26
|
+
- **`beginWindow(label)` / `endWindow(token)`.** Marks a span that must not lose its session, such as the interval between LOCK and UNLOCK. A teardown requested during an open window waits for it, bounded by an absolute ceiling measured from the request; on expiry the window is reported as abandoned rather than silently dropped.
|
|
27
|
+
- **The session lifecycle is on the shared contract, as capability atoms.** `AbstractAbapConnection` now declares `implements ISessionLifecycleAware, ILockWindowAware` from `@mcp-abap-adt/interfaces` 11.5.0, and `ITeardownReport`, `WindowToken`, `ADT_SESSION_ERROR` and `AdtSessionErrorCode` come from there. **Import them from `@mcp-abap-adt/interfaces`, not from this package** — it deliberately does not re-export them, because a contract type with two names is a contract type that can drift.
|
|
28
|
+
|
|
29
|
+
Atoms rather than five more methods on `IAbapConnection`: that interface is the minimum every transport can honour, and `RfcAbapConnection` owns no HTTP session and can open no lock window. Requiring these of every connection would force a transport with no session to implement a lie. Narrow to the atom you need — `IAbapConnection & ILockWindowAware` — and the compiler rejects an RFC connection at the call site instead of failing at runtime.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- **A replaced session is now detected and raised instead of absorbed.** Responses are observed through one path that updates the cookies *and* applies the identity policy together; ten call sites used to update the cookies alone, which mutated the fingerprint and made a replacement indistinguishable from the session it replaced. A lost session raises `ADT_SESSION_REPLACED` and tears down, rather than letting the next request run against a session the caller never opened.
|
|
33
|
+
- **Session verdicts survive the retry layers.** Three nested catches — the CSRF retry, the 401-on-GET path and the endpoint fallback — used to swallow a session verdict and retry into a *new* session, where the replacement read as `unchanged` and the loss was gone for good.
|
|
34
|
+
- **A failed establishment leaves nothing behind.** A rejecting response could still carry a `Set-Cookie`, and every auth subclass treats a cookie as proof that auth is settled, so the *next* `connect()` went out with no credentials at all and failed for an unrelated reason. Transport state and the session identity are both dropped when `establishSession()` throws; `getSessionIdentity()` no longer names a session that was never established.
|
|
35
|
+
- **Kerberos: the first challenge is diagnosed, not the fourth.** The connect-time CSRF fetch inherited a 3-retry default while a GSS token is one-shot, so the diagnosis was drawn from a replayed — or credential-less — request. Multi-leg SPNEGO (RFC 4559) is still unsupported, but a landscape that needs it now fails at `connect()` saying so, instead of being misreported as rejected credentials.
|
|
36
|
+
- **The CSRF token fetch stays inside the ADT conversation** (also released in 1.10.1).
|
|
37
|
+
- **The test suite is green on a clean install.** `rfc-params.test.ts` called `jest.mock()` on `@mcp-abap-adt/sap-rfc-lite`, an **optional** dependency with a native build against the SAP NW RFC SDK. On any machine without that SDK npm skips it silently and `jest.mock()` cannot resolve it, so the suite failed — for everyone but whoever had a `node_modules` left over from an install that succeeded. Mocked `{ virtual: true }` now: the test replaces the module entirely and never wanted the real one.
|
|
38
|
+
|
|
39
|
+
### Security
|
|
40
|
+
- Production audit is clean. `brace-expansion` remains reachable only through `jest` and is pinned by an override; it never ships.
|
|
41
|
+
|
|
42
|
+
### Dependencies
|
|
43
|
+
- `@mcp-abap-adt/interfaces` 7.2.0 → **11.5.0**, now a real requirement rather than a version bump: this release imports the connection capability atoms from it. Crossing 8–11 was a no-op — those breaking changes are all in ADT object capability types, which the connector never imports — and it also closes the drift against `adt-clients` and `auth-providers`, both already on 11.x.
|
|
44
|
+
|
|
45
|
+
## [1.10.2] - 2026-07-27
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
- **`SessionLifecycle` — the session-lifecycle core, internal for now.** Owns what the connection cannot express today: session state and identity, a serializing tail for lifecycle transitions, admission accounting with a teardown epoch, lock windows counted per occurrence, and a drain bounded by an absolute ceiling. It knows nothing of SAP, HTTP, RFC or cookies — identities are opaque `name → value` maps, windows are opaque labels — which is why its 29 tests need no server. **Not exported from the package index and not yet used by any connection**, so this release changes no behaviour and no public API; it lands the piece that the rest of the session work (fr0ster/mcp-abap-connection#15) will be composed from. Design: `docs/superpowers/specs/2026-07-27-session-lifecycle-design.md` in `@mcp-abap-adt/adt-clients`.
|
|
49
|
+
|
|
50
|
+
## [1.10.1] - 2026-07-27
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
- **CSRF token fetch now stays inside the ADT conversation.** `makeAdtRequest` sends `sap-adt-connection-id` on every request, for all session types, but the token fetch assembled its own headers (auth + `x-csrf-token: fetch` + `Accept` + `Cookie`) and omitted it. A fetch triggered while a lock was held therefore reached the server as a caller that merely presented the same cookies, with no way for either side to relate it to the conversation that opened the session. The fetch now carries the connection id like every other request.
|
|
54
|
+
|
|
55
|
+
## [1.10.0] - 2026-07-16
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
- **Uninterruptible critical sections for lock → modify → unlock chains.** A short per-request timeout was aborting requests mid-flight during a stateful lock → PUT/activate → unlock chain; aborting the socket drops the stateful ADT session and orphans the lock handle, leaving the object **locked and inactive**. New connection methods `beginCriticalSection()` / `endCriticalSection()` (reference-counted) plus `isInCriticalSection()`: while in a critical section, `makeAdtRequest` raises the effective timeout to a large ceiling (`getCriticalSectionTimeout()`, env `SAP_TIMEOUT_CRITICAL`, default `600000` ms) instead of the short per-request timeout, so slow PUT/activate/unlock requests run to completion rather than being interrupted. Consumers wrap a mutating operation with `beginCriticalSection()` before locking and `endCriticalSection()` in a `finally` after unlocking. Additive and backward-compatible (no behavior change outside a critical section).
|
|
59
|
+
|
|
60
|
+
## [1.9.1] - 2026-05-24
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
- **NTLM hard-reject for Kerberos auth.** When `KerberosAbapConnection` receives a 401/403 whose `WWW-Authenticate` header indicates NTLM (direct `NTLM` scheme, or an NTLM token tunneled via `Negotiate` — base64 prefix `TlRMTVNTUAA` = `NTLMSSP\0`), it now throws a clear error instead of swallowing it. Prevents a silent downgrade to weaker NTLM; only Kerberos/SPNEGO is accepted. New `isNtlmChallenge()` helper (`src/auth/ntlm.ts`).
|
|
64
|
+
|
|
65
|
+
## [1.9.0] - 2026-05-24
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
|
|
69
|
+
- **Certificate (mTLS) authentication** — `CertificateAbapConnection` injects client-cert material into the axios `https.Agent` via a new protected `getHttpsAgentOptions()` hook on `AbstractAbapConnection`. Material loaded from PEM (`certPath`+`certKeyPath`) or PFX (`certPfxPath`+`certPassphrase`) by the injectable `FileCertificateMaterialLoader` (`ICertificateMaterialLoader`).
|
|
70
|
+
- **Kerberos / SPNEGO authentication** — `KerberosAbapConnection` generates a single-leg Negotiate token locally via `generateSpnegoToken()` (lazy wrapper over the optional `kerberos` native package, declared in `optionalDependencies`), sends `Authorization: Negotiate <token>` on the first request, then reuses the SAP session cookie.
|
|
71
|
+
- `createAbapConnection()` routes `authType: 'certificate'` and `'kerberos'`; both reject `connectionType: 'rfc'`. New optional `certLoader` factory option.
|
|
72
|
+
- `sapConfigSignature()` includes cert paths / SPN (secrets never embedded — passphrase recorded as `'set'`/null only).
|
|
73
|
+
|
|
74
|
+
### Notes
|
|
75
|
+
|
|
76
|
+
- Certificate and Kerberos are connection-layer auth types (on-prem HTTP); they bypass the auth-broker and auth-providers. Requires `@mcp-abap-adt/interfaces@^7.2.0`.
|
|
77
|
+
- Both connections require `connect()` before the first request; calling a request first fails loudly (cert: throws on missing material; kerberos: throws on missing token).
|
|
78
|
+
|
|
79
|
+
## [1.7.0] - 2026-04-14
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- Update `@mcp-abap-adt/interfaces` to `^7.0.0` (adds `ServiceBindingVariant` type and `connect()` method in `IAbapConnection`)
|
|
84
|
+
|
|
85
|
+
## 1.5.3 - 2026-03-12
|
|
86
|
+
|
|
87
|
+
### Added
|
|
88
|
+
- **RFC stateful session support**: `setSessionType('stateful')` now injects `x-sap-adt-sessiontype: stateful` header and captures `set-cookie` from LOCK responses for cookie replay in subsequent requests (PUT, UNLOCK). This enables lock/update/unlock workflows for package objects over RFC, which require HTTP session ownership validation. `setSessionType('stateless')` clears the captured cookie.
|
|
89
|
+
|
|
90
|
+
## 1.5.2 - 2026-03-12
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
- **RFC debug logging**: `RfcAbapConnection` now logs full request headers, request body, response headers, and response body at `debug` level. Enable with `DEBUG_CONNECTORS=true` and `AUTH_LOG_LEVEL=debug`.
|
|
94
|
+
|
|
95
|
+
## [1.5.1] - 2026-03-09
|
|
96
|
+
|
|
97
|
+
### Fixed
|
|
98
|
+
- **RFC query params encoding**: `RfcAbapConnection.makeAdtRequest` now encodes `params` into the URI query string. Previously `params` were silently ignored, causing failures for package validation, transport checks, and any ADT operation using query parameters over RFC connections.
|
|
99
|
+
|
|
100
|
+
## [1.4.2] - 2026-03-06
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
- `reset()` method on `RfcAbapConnection` — delegates to `close()` for interface compatibility with HTTP connections.
|
|
104
|
+
|
|
105
|
+
## [1.4.1] - 2026-03-06
|
|
106
|
+
|
|
107
|
+
### Fixed
|
|
108
|
+
- Fix RFC STATUS_LINE parsing: use correct field names `STATUS_CODE`/`REASON_PHRASE` (not `CODE`/`REASON`). STATUS_CODE is returned as string — now parsed with `parseInt`.
|
|
109
|
+
- Remove `sap-client` URI parameter from RFC requests — the RFC session is already logged into the correct client via connection parameters. Adding `sap-client` caused "object not found" on some systems.
|
|
110
|
+
- Add fallback exception XML detection: when STATUS_LINE is empty (legacy systems), parse `<exc:exception>` body to derive HTTP status codes (404, 403, 409, 423, etc.).
|
|
111
|
+
|
|
112
|
+
## [1.4.0] - 2026-03-06
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
- `RfcAbapConnection` — RFC-based connection for legacy SAP systems (BASIS < 7.50) that don't support stateful HTTP sessions. Uses standard `SADT_REST_RFC_ENDPOINT` FM (the same FM that Eclipse ADT uses via JCo) to tunnel ADT REST requests over RFC. Solves HTTP 423 "invalid lock handle" on older systems.
|
|
116
|
+
- `authType: 'rfc'` support in `createAbapConnection()` factory.
|
|
117
|
+
- RFC connection parameters (ashost, sysnr) are derived from the existing `config.url` field — no config changes needed.
|
|
118
|
+
|
|
119
|
+
### Changed
|
|
120
|
+
- Updated dependency `@mcp-abap-adt/interfaces` to `^2.7.0` (adds `'rfc'` to `SapAuthType` union).
|
|
121
|
+
|
|
122
|
+
### Notes
|
|
123
|
+
- `node-rfc` is **not** a declared dependency. Users who need RFC connections must install it manually (`npm install node-rfc`) along with SAP NW RFC SDK.
|
|
124
|
+
- RFC connections are inherently stateful — `setSessionType()` is a no-op.
|
|
125
|
+
|
|
126
|
+
## [1.1.0] - 2026-02-13
|
|
127
|
+
|
|
128
|
+
### Added
|
|
129
|
+
- Added generic `GenericWebSocketTransport` implementation with injected WS factory and message envelope handling.
|
|
130
|
+
- Re-exported WebSocket transport interfaces from `@mcp-abap-adt/interfaces` and transport class from package root.
|
|
131
|
+
|
|
132
|
+
### Changed
|
|
133
|
+
- Updated dependency `@mcp-abap-adt/interfaces` to `^2.4.0`.
|
|
134
|
+
|
|
135
|
+
## [1.0.1] - 2026-02-10
|
|
136
|
+
|
|
137
|
+
### Changed
|
|
138
|
+
- Dependency updates: `axios`, `commander`, `@biomejs/biome`, `@types/node`.
|
|
139
|
+
|
|
140
|
+
## [1.0.0] - 2026-02-10
|
|
141
|
+
|
|
142
|
+
### Added
|
|
143
|
+
- `SamlAbapConnection` for cookie-based SAML sessions and `createAbapConnection` support for `authType: 'saml'`.
|
|
144
|
+
- SAML session cookie support in `SapConfig` and `sapConfigSignature()`.
|
|
145
|
+
- Unit tests for SAML connection, connection factory routing, and config signature.
|
|
146
|
+
|
|
147
|
+
### Changed
|
|
148
|
+
- **Conditional Logging Support**: Connection package now fully supports conditional logging via `undefined` logger
|
|
149
|
+
- When `undefined` is passed as logger parameter, connection operates silently (no logging output)
|
|
150
|
+
- This enables test environments to control logging verbosity via environment variables
|
|
151
|
+
- Tests can now pass `undefined` logger when `DEBUG_CONNECTION`, `DEBUG_CONN`, or `DEBUG_CONNECTORS` are not set
|
|
152
|
+
- Connection uses optional chaining (`logger?.info()`, `logger?.debug()`, etc.) for all logging calls
|
|
153
|
+
- No breaking changes - existing code with logger continues to work as before
|
|
154
|
+
|
|
155
|
+
## [0.2.8] - 2025-12-24
|
|
156
|
+
|
|
157
|
+
### Changed
|
|
158
|
+
- **Dependencies**: Updated `@mcp-abap-adt/interfaces` from `^0.2.5` to `^0.2.13`
|
|
159
|
+
|
|
160
|
+
## [0.2.7] - 2025-12-23
|
|
161
|
+
### Fixed
|
|
162
|
+
- Fixed LICENSE file - corrected copyright attribution (removed incorrect fork author)
|
|
163
|
+
|
|
164
|
+
## [0.2.6] - 2025-12-22
|
|
165
|
+
|
|
166
|
+
### Changed
|
|
167
|
+
- **Biome Migration**: Migrated from ESLint/Prettier to Biome for linting and formatting
|
|
168
|
+
- Added `@biomejs/biome` as dev dependency
|
|
169
|
+
- Added `lint`, `lint:check`, and `format` scripts to package.json
|
|
170
|
+
- Integrated Biome check into build process (`npx biome check src --diagnostic-level=error`)
|
|
171
|
+
- Updated Node.js imports to use `node:` protocol (`crypto`, `https`)
|
|
172
|
+
- **Type Safety**: Improved type safety by replacing `any` with `unknown`
|
|
173
|
+
- `AbstractAbapConnection.ts`: `updateCookiesFromResponse` method parameter changed from `Record<string, any>` to `Record<string, unknown>`
|
|
174
|
+
- `tokenRefresh.ts`: `error` parameter in catch block changed from `any` to `unknown` with added type guards
|
|
175
|
+
|
|
176
|
+
### Fixed
|
|
177
|
+
- Fixed computed property access by using literal keys where possible (`Authorization`, `Accept`, `Cookie` headers)
|
|
178
|
+
- Fixed non-null assertions by adding proper null checks (`JwtAbapConnection.ts`)
|
|
179
|
+
- Fixed optional chaining usage in `tokenRefresh.ts`
|
|
180
|
+
- Removed unused imports (`AbapConnection.ts`)
|
|
181
|
+
- Improved error handling with proper type guards for `unknown` error types
|
|
182
|
+
|
|
183
|
+
## [0.2.5] - 2025-12-21
|
|
184
|
+
|
|
185
|
+
### Added
|
|
186
|
+
- **connectionFactory tokenRefresher**: `createAbapConnection()` now accepts optional 4th parameter `tokenRefresher`
|
|
187
|
+
- Passes through to `JwtAbapConnection` for automatic token refresh DI
|
|
188
|
+
- Enables external token management via `AuthBroker.createTokenRefresher()`
|
|
189
|
+
|
|
190
|
+
## [0.2.4] - 2025-12-21
|
|
191
|
+
|
|
192
|
+
### Added
|
|
193
|
+
- **ITokenRefresher Support**: `JwtAbapConnection` now supports automatic token refresh via dependency injection
|
|
194
|
+
- New optional `tokenRefresher` parameter in constructor
|
|
195
|
+
- If provided, 401/403 errors trigger automatic token refresh and request retry
|
|
196
|
+
- If not provided, legacy behavior (throw error on expired token)
|
|
197
|
+
- Works with `AuthBroker.createTokenRefresher(destination)` from `@mcp-abap-adt/auth-broker`
|
|
198
|
+
|
|
199
|
+
### Changed
|
|
200
|
+
- **Dependencies**: Updated `@mcp-abap-adt/interfaces` to `^0.2.5`
|
|
201
|
+
- New `ITokenRefresher` interface for token management DI
|
|
202
|
+
- Simplified `IAbapConnection` interface
|
|
203
|
+
|
|
204
|
+
### Usage Example
|
|
205
|
+
```typescript
|
|
206
|
+
import { JwtAbapConnection } from '@mcp-abap-adt/connection';
|
|
207
|
+
import { AuthBroker } from '@mcp-abap-adt/auth-broker';
|
|
208
|
+
|
|
209
|
+
// Create token refresher from broker
|
|
210
|
+
const tokenRefresher = broker.createTokenRefresher('TRIAL');
|
|
211
|
+
|
|
212
|
+
// Inject into connection - 401/403 handled automatically
|
|
213
|
+
const connection = new JwtAbapConnection(config, logger, sessionId, tokenRefresher);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## [0.2.3] - 2025-12-19
|
|
217
|
+
|
|
218
|
+
### Fixed
|
|
219
|
+
- **Network Error Detection**: Add proper detection and handling of network-level errors in `AbstractAbapConnection.makeAdtRequest()`
|
|
220
|
+
- Detect network errors: `ECONNREFUSED`, `ETIMEDOUT`, `ENOTFOUND`, `ECONNRESET`, `ENETUNREACH`, `EHOSTUNREACH`
|
|
221
|
+
- Skip retry logic for network errors (CSRF token retry, 401 cookie retry)
|
|
222
|
+
- Throw network errors immediately with clear error message
|
|
223
|
+
- Prevents confusing error messages when VPN is down or server is unreachable
|
|
224
|
+
- Network errors now clearly indicate infrastructure issues vs application errors
|
|
225
|
+
|
|
226
|
+
### Changed
|
|
227
|
+
- **Error Handling**: Improved error handling logic to distinguish between network errors and HTTP errors
|
|
228
|
+
- Network errors (connection issues) are now handled separately from HTTP errors (401, 403, 404)
|
|
229
|
+
- No retry attempts for network errors (retries cannot fix infrastructure issues)
|
|
230
|
+
- Better error logging with network error context
|
|
231
|
+
|
|
232
|
+
### Documentation
|
|
233
|
+
- Added "Network Error Detection" section to `docs/USAGE.md` with examples and best practices
|
|
234
|
+
- Documented all detected network error codes and their meanings
|
|
235
|
+
- Added error handling examples showing how to handle network vs HTTP errors
|
|
236
|
+
|
|
237
|
+
## [0.2.2] - 2025-12-13
|
|
238
|
+
|
|
239
|
+
### Fixed
|
|
240
|
+
- Add missing `ILogger` import from `@mcp-abap-adt/interfaces` to restore TypeScript build
|
|
241
|
+
|
|
242
|
+
## [0.2.1] - 2025-12-13
|
|
243
|
+
|
|
244
|
+
### Changed
|
|
245
|
+
- Dependency bump: `@mcp-abap-adt/interfaces` → `^0.1.16` to align with latest interfaces release
|
|
246
|
+
- Repository metadata: point package links to `fr0ster/mcp-abap-connection` (correct repo)
|
|
247
|
+
|
|
248
|
+
## [0.2.0] - 2025-12-08
|
|
249
|
+
|
|
250
|
+
### Breaking Changes
|
|
251
|
+
|
|
252
|
+
- **Token Refresh Removed**: Token refresh functionality has been completely removed from this package
|
|
253
|
+
- `refreshToken()` method removed from `JwtAbapConnection`
|
|
254
|
+
- `canRefreshToken()` method removed from `JwtAbapConnection`
|
|
255
|
+
- All automatic token refresh logic removed from connection classes
|
|
256
|
+
- Token refresh is now handled exclusively by `@mcp-abap-adt/auth-broker` package
|
|
257
|
+
- This is a breaking change - code that relied on connection-level token refresh will need to use auth-broker instead
|
|
258
|
+
|
|
259
|
+
- **Logger is Optional**: Logger parameter is now optional in all connection constructors
|
|
260
|
+
- `BaseAbapConnection`, `JwtAbapConnection`, and `createAbapConnection()` now accept `logger?: ILogger | null`
|
|
261
|
+
- All logger calls use optional chaining (`logger?.info()`, `logger?.debug()`, etc.)
|
|
262
|
+
- If no logger is provided, no logging output is produced (no-op behavior)
|
|
263
|
+
- This allows using connections without requiring a logger instance
|
|
264
|
+
|
|
265
|
+
- **Session Storage Removed**: Session storage functionality has been completely removed from this package
|
|
266
|
+
- `sessionStorage` parameter removed from all connection constructors (`BaseAbapConnection`, `JwtAbapConnection`, `createAbapConnection()`)
|
|
267
|
+
- All session storage methods removed: `setSessionStorage()`, `getSessionStorage()`, `loadSessionState()`, `saveSessionState()`, `clearSessionState()`, `getSessionState()`, `setSessionState()`
|
|
268
|
+
- `FileSessionStorage` utility class removed
|
|
269
|
+
- Session state persistence is now handled exclusively by `@mcp-abap-adt/auth-broker` package
|
|
270
|
+
- Connection package now handles only HTTP communication and session headers (cookies, CSRF tokens) without persistence
|
|
271
|
+
- This is a breaking change - code that relied on connection-level session storage will need to use auth-broker instead
|
|
272
|
+
|
|
273
|
+
### Changed
|
|
274
|
+
|
|
275
|
+
- **Connection Package Scope**: Package now focuses solely on HTTP connection management
|
|
276
|
+
- Removed all token refresh logic from `JwtAbapConnection`
|
|
277
|
+
- Removed all token refresh logic from `connect()`, `makeAdtRequest()`, and `fetchCsrfToken()` methods
|
|
278
|
+
- Removed all session storage and state persistence logic
|
|
279
|
+
- Connection package now handles only HTTP communication and session headers (cookies, CSRF tokens)
|
|
280
|
+
- Token lifecycle management and session state persistence are delegated to auth-broker package
|
|
281
|
+
|
|
282
|
+
### Removed
|
|
283
|
+
|
|
284
|
+
- **Token Refresh Methods**:
|
|
285
|
+
- `refreshToken()` method removed from `JwtAbapConnection`
|
|
286
|
+
- `canRefreshToken()` method removed from `JwtAbapConnection`
|
|
287
|
+
- `tokenRefreshInProgress` private field removed
|
|
288
|
+
- Import of `refreshJwtToken` utility removed
|
|
289
|
+
|
|
290
|
+
- **Token Refresh Tests**:
|
|
291
|
+
- `auto-refresh.test.ts` removed
|
|
292
|
+
- Replaced with simplified `jwt-connection.test.ts` that tests only configuration validation
|
|
293
|
+
|
|
294
|
+
- **Session Storage Components**:
|
|
295
|
+
- `FileSessionStorage` utility class removed
|
|
296
|
+
- `ISessionStorage` and `SessionState` type exports removed
|
|
297
|
+
- All session storage related imports and exports removed
|
|
298
|
+
|
|
299
|
+
### Migration Guide
|
|
300
|
+
|
|
301
|
+
If you were using token refresh functionality:
|
|
302
|
+
|
|
303
|
+
**Before (0.1.x)**:
|
|
304
|
+
```typescript
|
|
305
|
+
const connection = new JwtAbapConnection(config, logger);
|
|
306
|
+
if (connection.canRefreshToken()) {
|
|
307
|
+
await connection.refreshToken();
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**After (0.2.0)**:
|
|
312
|
+
```typescript
|
|
313
|
+
// Token refresh is now handled by auth-broker
|
|
314
|
+
// Connection package only handles HTTP communication
|
|
315
|
+
const connection = new JwtAbapConnection(config, logger);
|
|
316
|
+
// No refreshToken() or canRefreshToken() methods available
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Logger Usage**:
|
|
320
|
+
```typescript
|
|
321
|
+
// Logger is now optional
|
|
322
|
+
const connection = new JwtAbapConnection(config); // No logger - no logging output
|
|
323
|
+
const connection = new JwtAbapConnection(config, logger); // With logger - logging enabled
|
|
324
|
+
const connection = new JwtAbapConnection(config, null); // Explicitly no logger
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
If you were using session storage functionality:
|
|
328
|
+
|
|
329
|
+
**Before (0.1.x)**:
|
|
330
|
+
```typescript
|
|
331
|
+
import { FileSessionStorage } from '@mcp-abap-adt/connection';
|
|
332
|
+
|
|
333
|
+
const sessionStorage = new FileSessionStorage();
|
|
334
|
+
const connection = new JwtAbapConnection(config, logger, sessionStorage);
|
|
335
|
+
await connection.saveSessionState();
|
|
336
|
+
const state = await connection.getSessionState();
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**After (0.2.0)**:
|
|
340
|
+
```typescript
|
|
341
|
+
// Session storage is now handled by auth-broker
|
|
342
|
+
// Connection package only handles HTTP communication
|
|
343
|
+
const connection = new JwtAbapConnection(config, logger);
|
|
344
|
+
// No sessionStorage parameter, no saveSessionState() or getSessionState() methods
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## [0.1.15] - 2025-12-05
|
|
348
|
+
|
|
349
|
+
### Changed
|
|
350
|
+
- **Logger Interface Migration**: Migrated from specialized logger methods to standard `ILogger` interface
|
|
351
|
+
- Replaced `logger.csrfToken()` calls with standard `debug()` and `error()` methods
|
|
352
|
+
- Replaced `logger.tlsConfig()` calls with standard `debug()` method
|
|
353
|
+
- Now uses only `ILogger` interface from `@mcp-abap-adt/interfaces` without dependency on concrete logger implementation
|
|
354
|
+
- Follows Dependency Inversion Principle - depends on interface, not implementation
|
|
355
|
+
|
|
356
|
+
### Added
|
|
357
|
+
- **npm Configuration**: Added `.npmrc` file with `prefer-online=true` to ensure packages are installed from npmjs.com registry instead of local file system dependencies
|
|
358
|
+
|
|
359
|
+
## [0.1.14] - 2025-12-04
|
|
360
|
+
|
|
361
|
+
### Added
|
|
362
|
+
- **Interfaces Package Integration**: Migrated to use `@mcp-abap-adt/interfaces` package for all interface definitions
|
|
363
|
+
- All interfaces now imported from shared package
|
|
364
|
+
- Backward compatibility maintained with type aliases
|
|
365
|
+
- Dependency on `@mcp-abap-adt/interfaces@^0.1.0` added
|
|
366
|
+
|
|
367
|
+
### Changed
|
|
368
|
+
- **Interface Renaming**: Interfaces renamed to follow `I` prefix convention:
|
|
369
|
+
- `SapConfig` → `ISapConfig` (type alias for backward compatibility)
|
|
370
|
+
- `AbapConnection` → `IAbapConnection` (type alias for backward compatibility)
|
|
371
|
+
- `AbapRequestOptions` → `IAbapRequestOptions` (type alias for backward compatibility)
|
|
372
|
+
- `SessionState` → `ISessionState` (type alias for backward compatibility)
|
|
373
|
+
- `TokenRefreshResult` → `ITokenRefreshResult` (type alias for backward compatibility)
|
|
374
|
+
- `TimeoutConfig` → `ITimeoutConfig` (type alias for backward compatibility)
|
|
375
|
+
- Old names still work via type aliases for backward compatibility
|
|
376
|
+
|
|
377
|
+
### Documentation
|
|
378
|
+
- **Responsibilities and Design Principles**: Added comprehensive documentation section explaining package responsibilities and design principles
|
|
379
|
+
|
|
380
|
+
## [0.1.13] - 2025-12-01
|
|
381
|
+
|
|
382
|
+
### Added
|
|
383
|
+
- **CSRF Configuration Export**: Exported `CSRF_CONFIG` and `CSRF_ERROR_MESSAGES` constants for consistent CSRF token handling across different connection implementations
|
|
384
|
+
- `CSRF_CONFIG`: Centralized constants for CSRF token fetching (retry count, delay, endpoint, headers)
|
|
385
|
+
- `CSRF_ERROR_MESSAGES`: Standardized error messages for CSRF token operations
|
|
386
|
+
- Enables other projects (e.g., Cloud SDK-based connections) to use the same CSRF configuration
|
|
387
|
+
- Rationale in commit `ba12a42`; the standalone proposal document it linked is no longer in the tree
|
|
388
|
+
|
|
389
|
+
### Changed
|
|
390
|
+
- **CSRF Token Endpoint**: Updated CSRF token fetching to use `/sap/bc/adt/core/discovery` endpoint instead of `/sap/bc/adt/discovery`
|
|
391
|
+
- Lighter response payload
|
|
392
|
+
- Available on all SAP systems (on-premise and cloud)
|
|
393
|
+
- Standard ADT discovery endpoint
|
|
394
|
+
|
|
395
|
+
## [0.1.12] - 2025-11-28
|
|
396
|
+
|
|
397
|
+
### Changed
|
|
398
|
+
- **BREAKING**: Removed all file reading functionality from connection package:
|
|
399
|
+
- Connection package no longer reads `.env` files or any configuration files
|
|
400
|
+
- Connection package no longer depends on `dotenv` or file system operations for configuration
|
|
401
|
+
- Consumers must now pass `SapConfig` directly to connection constructors
|
|
402
|
+
- This change improves separation of concerns: connection layer is now purely about connection logic, not configuration management
|
|
403
|
+
|
|
404
|
+
### Removed
|
|
405
|
+
- `loadEnvFile(envPath?: string): boolean` - Function that loaded `.env` files
|
|
406
|
+
- `loadConfigFromEnvFile(envPath?: string): SapConfig` - Convenience function that combined file loading and config reading
|
|
407
|
+
- `getConfigFromEnv(): SapConfig` - Function that read configuration from `process.env`
|
|
408
|
+
- All file system dependencies (`fs`, `path`) from `sapConfig.ts`
|
|
409
|
+
- All `dotenv` usage and dependencies from the package
|
|
410
|
+
|
|
411
|
+
### Fixed
|
|
412
|
+
- Resolved `stdio` mode output corruption issues by removing `dotenv` dependency
|
|
413
|
+
- Connection package is now cleaner and more focused on connection logic only
|
|
414
|
+
- Configuration management is now the responsibility of consumers (e.g., `mcp-abap-adt`)
|
|
415
|
+
|
|
416
|
+
### Migration Guide
|
|
417
|
+
If you were using `getConfigFromEnv()` or `loadConfigFromEnvFile()`:
|
|
418
|
+
1. Read environment variables in your application code (using `dotenv` or manual parsing)
|
|
419
|
+
2. Create `SapConfig` object from environment variables
|
|
420
|
+
3. Pass `SapConfig` directly to `createAbapConnection()` or connection constructors
|
|
421
|
+
|
|
422
|
+
Example:
|
|
423
|
+
```typescript
|
|
424
|
+
// Before (0.1.11 and earlier):
|
|
425
|
+
import { loadConfigFromEnvFile, createAbapConnection } from '@mcp-abap-adt/connection';
|
|
426
|
+
const config = loadConfigFromEnvFile();
|
|
427
|
+
const connection = createAbapConnection(config, logger);
|
|
428
|
+
|
|
429
|
+
// After (0.1.12+):
|
|
430
|
+
import { SapConfig, createAbapConnection } from '@mcp-abap-adt/connection';
|
|
431
|
+
// Load .env file in your application (using dotenv or manual parsing)
|
|
432
|
+
const config: SapConfig = {
|
|
433
|
+
url: process.env.SAP_URL!,
|
|
434
|
+
authType: 'jwt',
|
|
435
|
+
jwtToken: process.env.SAP_JWT_TOKEN!,
|
|
436
|
+
// ... other config
|
|
437
|
+
};
|
|
438
|
+
const connection = createAbapConnection(config, logger);
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## [0.1.11] - 2025-11-25
|
|
442
|
+
|
|
443
|
+
### Changed
|
|
444
|
+
- Updated documentation:
|
|
445
|
+
- `docs/JWT_AUTH_TOOLS.md`: Added examples showing token expiry information in generated `.env` files, explained automatic expiry detection feature
|
|
446
|
+
- `docs/INSTALLATION.md`: Updated JWT authentication section with token expiry examples, added manual setup option, updated version to 0.1.10
|
|
447
|
+
- Documentation now reflects the new token expiry feature introduced in 0.1.10 and provides clear guidance for users
|
|
448
|
+
|
|
449
|
+
## [0.1.10] - 2025-11-25
|
|
450
|
+
|
|
451
|
+
### Added
|
|
452
|
+
- Token expiry information in `.env` file generated by `sap-abap-auth` CLI:
|
|
453
|
+
- Automatic JWT token expiry date extraction and display
|
|
454
|
+
- Automatic refresh token expiry date extraction and display
|
|
455
|
+
- Human-readable expiry dates in UTC timezone
|
|
456
|
+
- ISO 8601 formatted expiry timestamps
|
|
457
|
+
- Comments added at the beginning of `.env` file for easy reference
|
|
458
|
+
- `getTokenExpiry()` utility function in `sap-abap-auth.js`:
|
|
459
|
+
- Decodes JWT tokens to extract expiration information
|
|
460
|
+
- Handles base64url encoding/decoding
|
|
461
|
+
- Returns structured expiry information (timestamp, date, readable format)
|
|
462
|
+
- Gracefully handles invalid or non-standard JWT tokens
|
|
463
|
+
|
|
464
|
+
### Changed
|
|
465
|
+
- Enhanced `updateEnvFile()` function in `sap-abap-auth.js`:
|
|
466
|
+
- Now includes token expiry comments at the beginning of `.env` files
|
|
467
|
+
- Provides clear visibility into when tokens will expire
|
|
468
|
+
- Helps users proactively refresh tokens before expiration
|
|
469
|
+
|
|
470
|
+
## [0.1.9] - 2025-11-23
|
|
471
|
+
|
|
472
|
+
### Changed
|
|
473
|
+
- Updated documentation in README.md:
|
|
474
|
+
- Added information about new API methods (`getSessionId()`, `setSessionType()`)
|
|
475
|
+
- Enhanced `AbapConnection` interface documentation
|
|
476
|
+
- Added Changelog section with link to CHANGELOG.md
|
|
477
|
+
- Fixed documentation links to use `docs/` directory
|
|
478
|
+
- Specified current version (0.1.8) with key features
|
|
479
|
+
- Updated CHANGELOG.md:
|
|
480
|
+
- Added detailed descriptions for all versions (0.1.1-0.1.8)
|
|
481
|
+
- Fixed version ordering (newest to oldest)
|
|
482
|
+
- Added proper version links for all releases
|
|
483
|
+
- Documented all features, changes, and fixes for each version
|
|
484
|
+
|
|
485
|
+
### Added
|
|
486
|
+
- Comprehensive version history documentation
|
|
487
|
+
- Version comparison links in CHANGELOG
|
|
488
|
+
|
|
489
|
+
## [0.1.8] - 2025-11-22
|
|
490
|
+
|
|
491
|
+
### Changed
|
|
492
|
+
- Refactored base URL handling in `AbstractAbapConnection`:
|
|
493
|
+
- Removed deprecated `setBaseUrl()` and `getBaseUrl()` methods
|
|
494
|
+
- Base URL now managed internally via constructor
|
|
495
|
+
- Improved URL construction consistency
|
|
496
|
+
- Enhanced session management:
|
|
497
|
+
- Added `getSessionId()` method to retrieve current session ID
|
|
498
|
+
- Added `setSessionType()` method to switch between stateful/stateless modes
|
|
499
|
+
- Session ID now auto-generated if not provided
|
|
500
|
+
- Improved session state management in `AbstractAbapConnection`
|
|
501
|
+
|
|
502
|
+
### Added
|
|
503
|
+
- cSpell configuration for custom words in settings.json
|
|
504
|
+
- Automatic session ID generation when not explicitly provided
|
|
505
|
+
- GitHub Actions workflow for automated release process
|
|
506
|
+
- Environment file loading and configuration utilities
|
|
507
|
+
- `getSessionId()` and `setSessionType()` public methods for better session control
|
|
508
|
+
|
|
509
|
+
### Removed
|
|
510
|
+
- Deprecated `setBaseUrl()` and `getBaseUrl()` methods from `AbstractAbapConnection`
|
|
511
|
+
- Use constructor parameter instead for setting base URL
|
|
512
|
+
|
|
513
|
+
### Fixed
|
|
514
|
+
- Session ID generation now more robust
|
|
515
|
+
- Base URL handling more consistent across connection types
|
|
516
|
+
|
|
517
|
+
## [0.1.7] - 2025-11-22
|
|
518
|
+
|
|
519
|
+
### Changed
|
|
520
|
+
- Refactored base URL handling in `AbstractAbapConnection`:
|
|
521
|
+
- Base URL construction now centralized and consistent
|
|
522
|
+
- Improved URL parsing and validation
|
|
523
|
+
- Removed deprecated URL handling methods
|
|
524
|
+
|
|
525
|
+
### Removed
|
|
526
|
+
- Deprecated methods for base URL manipulation
|
|
527
|
+
- Use constructor-based URL configuration instead
|
|
528
|
+
|
|
529
|
+
## [0.1.6] - 2025-11-22
|
|
530
|
+
|
|
531
|
+
### Added
|
|
532
|
+
- `getSessionId()` method to retrieve current session ID
|
|
533
|
+
- `setSessionType()` method to programmatically switch between stateful/stateless modes
|
|
534
|
+
- Better session management API for external control
|
|
535
|
+
|
|
536
|
+
### Changed
|
|
537
|
+
- Enhanced session management with more granular control
|
|
538
|
+
- Session type can now be changed after connection creation
|
|
539
|
+
|
|
540
|
+
## [0.1.5] - 2025-11-22
|
|
541
|
+
|
|
542
|
+
### Changed
|
|
543
|
+
- Refactored session ID generation and state management in `AbstractAbapConnection`
|
|
544
|
+
- Improved session state persistence logic
|
|
545
|
+
- Better handling of session lifecycle
|
|
546
|
+
|
|
547
|
+
### Fixed
|
|
548
|
+
- Session state management edge cases
|
|
549
|
+
- Session ID consistency across connection lifecycle
|
|
550
|
+
|
|
551
|
+
## [0.1.4] - 2025-11-21
|
|
552
|
+
|
|
553
|
+
### Added
|
|
554
|
+
- Automatic session ID generation when not explicitly provided
|
|
555
|
+
- Session ID now auto-generated using UUID if not specified
|
|
556
|
+
- Improved session management for stateful connections
|
|
557
|
+
|
|
558
|
+
### Changed
|
|
559
|
+
- Session creation logic simplified - no manual ID required
|
|
560
|
+
- Default session behavior more intuitive
|
|
561
|
+
|
|
562
|
+
## [0.1.3] - 2025-11-20
|
|
563
|
+
|
|
564
|
+
### Added
|
|
565
|
+
- GitHub Actions workflow for automated release process
|
|
566
|
+
- Automated npm publishing on version tags
|
|
567
|
+
- CI/CD pipeline for package releases
|
|
568
|
+
|
|
569
|
+
### Changed
|
|
570
|
+
- Release process now automated via GitHub Actions
|
|
571
|
+
- Version tagging triggers automatic npm publish
|
|
572
|
+
|
|
573
|
+
## [0.1.2] - 2025-11-20
|
|
574
|
+
|
|
575
|
+
### Changed
|
|
576
|
+
- Updated dependencies to latest versions
|
|
577
|
+
- Enhanced TypeScript configuration for better type safety
|
|
578
|
+
- Improved build output structure
|
|
579
|
+
|
|
580
|
+
### Added
|
|
581
|
+
- Better TypeScript compiler options
|
|
582
|
+
- Stricter type checking enabled
|
|
583
|
+
|
|
584
|
+
## 0.1.0 - 2024-11-14
|
|
585
|
+
|
|
586
|
+
### Changed
|
|
587
|
+
- **BREAKING**: Architecture refactoring for proper separation of concerns:
|
|
588
|
+
- `connect()` method changed from concrete to **abstract** in `AbstractAbapConnection`
|
|
589
|
+
- Each authentication type now implements its own `connect()` logic:
|
|
590
|
+
- `BaseAbapConnection`: Basic auth with CSRF token fetch, logs warnings on errors
|
|
591
|
+
- `JwtAbapConnection`: JWT auth with automatic token refresh on 401/403 errors
|
|
592
|
+
- `fetchCsrfToken()` changed from `private` to `protected` for use by concrete implementations
|
|
593
|
+
- Added protected getters/setters: `getCsrfToken()`, `setCsrfToken()`, `getCookies()`
|
|
594
|
+
- Removed ALL JWT-specific logic from `AbstractAbapConnection`:
|
|
595
|
+
- Removed JWT expiration checks from `connect()`
|
|
596
|
+
- Removed JWT error handling from base class
|
|
597
|
+
- Base class is now completely auth-agnostic
|
|
598
|
+
- `JwtAbapConnection.connect()` now handles:
|
|
599
|
+
- Token expiration detection (401/403 errors)
|
|
600
|
+
- Permission vs auth error distinction (`ExceptionResourceNoAccess` check)
|
|
601
|
+
- Automatic token refresh and retry
|
|
602
|
+
- `JwtAbapConnection.makeAdtRequest()` override handles JWT refresh for regular requests
|
|
603
|
+
- Previous architecture cleanup (from earlier versions):
|
|
604
|
+
- `BaseAbapConnection` (abstract) → `AbstractAbapConnection`
|
|
605
|
+
- `OnPremAbapConnection` → `BaseAbapConnection`
|
|
606
|
+
- `CloudAbapConnection` → `JwtAbapConnection`
|
|
607
|
+
|
|
608
|
+
### Added
|
|
609
|
+
- Automatic JWT token refresh functionality for cloud connections
|
|
610
|
+
- Auto-refresh on 401/403 errors in both `connect()` and `makeAdtRequest()`
|
|
611
|
+
- Permission error detection: skips refresh for "ExceptionResourceNoAccess", "No authorization", "Missing authorization"
|
|
612
|
+
- `canRefreshToken()` method to check if refresh credentials available
|
|
613
|
+
- `refreshToken()` method to refresh JWT using UAA OAuth2 endpoint
|
|
614
|
+
- Concurrent refresh protection (prevents multiple simultaneous refresh attempts)
|
|
615
|
+
- Protected helper methods in `AbstractAbapConnection` for subclass use:
|
|
616
|
+
- `fetchCsrfToken()` - CSRF token fetching with retry logic
|
|
617
|
+
- `getCsrfToken()`, `setCsrfToken()` - CSRF token management
|
|
618
|
+
- `getCookies()` - Cookie access for concrete implementations
|
|
619
|
+
- Unit tests for auto-refresh logic (`src/__tests__/auto-refresh.test.ts`)
|
|
620
|
+
- Documentation structure:
|
|
621
|
+
- `docs/INSTALLATION.md` - Installation guide
|
|
622
|
+
- `docs/USAGE.md` - Usage examples and API documentation
|
|
623
|
+
- `docs/CUSTOM_SESSION_STORAGE.md` - Custom session storage implementation
|
|
624
|
+
- Example files:
|
|
625
|
+
- `examples/basic-connection.js` - Simple connection example
|
|
626
|
+
- `examples/session-persistence.js` - FileSessionStorage usage
|
|
627
|
+
- Updated `examples/README.md` with all examples
|
|
628
|
+
|
|
629
|
+
### Removed
|
|
630
|
+
- JWT-specific logic from `AbstractAbapConnection`:
|
|
631
|
+
- Removed `isJwtExpiredError()` helper method
|
|
632
|
+
- Removed JWT refresh logic from base `connect()` method
|
|
633
|
+
- Removed JWT error messages from abstract class
|
|
634
|
+
- `AbstractAbapConnection` from public exports (internal use only)
|
|
635
|
+
- Only `BaseAbapConnection` and `JwtAbapConnection` are exported publicly
|
|
636
|
+
- `AUTO_REFRESH_IMPROVEMENTS.md` (temporary document, content moved to CHANGELOG)
|
|
637
|
+
- `CONNECTION_LAYER_ROADMAP.md` (roadmap belongs in root project)
|
|
638
|
+
- `PUBLICATION_ROADMAP.md` (roadmap belongs in root project)
|
|
639
|
+
|
|
640
|
+
### Fixed
|
|
641
|
+
- JWT token refresh now properly handles connection errors (401/403 during initial connect)
|
|
642
|
+
- Permission errors (403 with "ExceptionResourceNoAccess") no longer trigger JWT refresh loops
|
|
643
|
+
- Proper separation: base class handles HTTP/session, concrete classes handle auth-specific errors
|
|
644
|
+
- Auto-refresh not triggering due to `canRefreshToken()` returning false
|
|
645
|
+
- Root cause: Test configuration not reading UAA credentials from environment
|
|
646
|
+
- Fixed in `packages/adt-clients` by updating `getConfig()` to read UAA variables
|
|
647
|
+
|
|
648
|
+
## 0.1.0 - 2024-11-14
|
|
649
|
+
|
|
650
|
+
### Changed
|
|
651
|
+
- **BREAKING**: Architecture refactoring for proper separation of concerns:
|
|
652
|
+
- `connect()` method changed from concrete to **abstract** in `AbstractAbapConnection`
|
|
653
|
+
- Each authentication type now implements its own `connect()` logic:
|
|
654
|
+
- `BaseAbapConnection`: Basic auth with CSRF token fetch, logs warnings on errors
|
|
655
|
+
- `JwtAbapConnection`: JWT auth with automatic token refresh on 401/403 errors
|
|
656
|
+
- `fetchCsrfToken()` changed from `private` to `protected` for use by concrete implementations
|
|
657
|
+
- Added protected getters/setters: `getCsrfToken()`, `setCsrfToken()`, `getCookies()`
|
|
658
|
+
- Removed ALL JWT-specific logic from `AbstractAbapConnection`:
|
|
659
|
+
- Removed JWT expiration checks from `connect()`
|
|
660
|
+
- Removed JWT error handling from base class
|
|
661
|
+
- Base class is now completely auth-agnostic
|
|
662
|
+
- `JwtAbapConnection.connect()` now handles:
|
|
663
|
+
- Token expiration detection (401/403 errors)
|
|
664
|
+
- Permission vs auth error distinction (`ExceptionResourceNoAccess` check)
|
|
665
|
+
- Automatic token refresh and retry
|
|
666
|
+
- `JwtAbapConnection.makeAdtRequest()` override handles JWT refresh for regular requests
|
|
667
|
+
- Previous architecture cleanup (from earlier versions):
|
|
668
|
+
- `BaseAbapConnection` (abstract) → `AbstractAbapConnection`
|
|
669
|
+
- `OnPremAbapConnection` → `BaseAbapConnection`
|
|
670
|
+
- `CloudAbapConnection` → `JwtAbapConnection`
|
|
671
|
+
|
|
672
|
+
### Added
|
|
673
|
+
- Initial release of `@mcp-abap-adt/connection` package
|
|
674
|
+
- Support for Basic Auth (on-premise systems)
|
|
675
|
+
- Support for JWT/OAuth2 (SAP BTP cloud systems)
|
|
676
|
+
- CSRF token management
|
|
677
|
+
- Cookie-based session management
|
|
678
|
+
- `FileSessionStorage` for session persistence
|
|
679
|
+
- `ISessionStorage` interface for custom session storage
|
|
680
|
+
- CLI tool (`sap-abap-auth`) for browser-based authentication
|
|
681
|
+
- TypeScript type definitions
|
|
682
|
+
- Configurable timeouts for different operation types
|
|
683
|
+
- Custom logger interface (`ILogger`)
|
|
684
|
+
- Connection factory (`createAbapConnection()`)
|
|
685
|
+
- `BaseAbapConnection` for basic auth (formerly `OnPremAbapConnection`)
|
|
686
|
+
- `JwtAbapConnection` for JWT auth (formerly `CloudAbapConnection`)
|
|
687
|
+
- Session state management (`getSessionState()`, `setSessionState()`)
|
|
688
|
+
- Automatic JWT token refresh functionality for cloud connections
|
|
689
|
+
- Auto-refresh on 401/403 errors in both `connect()` and `makeAdtRequest()`
|
|
690
|
+
- Permission error detection: skips refresh for "ExceptionResourceNoAccess", "No authorization", "Missing authorization"
|
|
691
|
+
- `canRefreshToken()` method to check if refresh credentials available
|
|
692
|
+
- `refreshToken()` method to refresh JWT using UAA OAuth2 endpoint
|
|
693
|
+
- Concurrent refresh protection (prevents multiple simultaneous refresh attempts)
|
|
694
|
+
- Protected helper methods in `AbstractAbapConnection` for subclass use:
|
|
695
|
+
- `fetchCsrfToken()` - CSRF token fetching with retry logic
|
|
696
|
+
- `getCsrfToken()`, `setCsrfToken()` - CSRF token management
|
|
697
|
+
- `getCookies()` - Cookie access for concrete implementations
|
|
698
|
+
- Unit tests for auto-refresh logic (`src/__tests__/auto-refresh.test.ts`)
|
|
699
|
+
- Documentation structure:
|
|
700
|
+
- `docs/INSTALLATION.md` - Installation guide
|
|
701
|
+
- `docs/USAGE.md` - Usage examples and API documentation
|
|
702
|
+
- `docs/CUSTOM_SESSION_STORAGE.md` - Custom session storage implementation
|
|
703
|
+
- `docs/STATEFUL_SESSION_GUIDE.md` - Session state management guide
|
|
704
|
+
- Example files:
|
|
705
|
+
- `examples/basic-connection.js` - Simple connection example
|
|
706
|
+
- `examples/session-persistence.js` - FileSessionStorage usage
|
|
707
|
+
- `examples/README.md` with all examples
|
|
708
|
+
|
|
709
|
+
### Removed
|
|
710
|
+
- JWT-specific logic from `AbstractAbapConnection`:
|
|
711
|
+
- Removed `isJwtExpiredError()` helper method
|
|
712
|
+
- Removed JWT refresh logic from base `connect()` method
|
|
713
|
+
- Removed JWT error messages from abstract class
|
|
714
|
+
- `AbstractAbapConnection` from public exports (internal use only)
|
|
715
|
+
- Only `BaseAbapConnection` and `JwtAbapConnection` are exported publicly
|
|
716
|
+
|
|
717
|
+
### Fixed
|
|
718
|
+
- JWT token refresh now properly handles connection errors (401/403 during initial connect)
|
|
719
|
+
- Permission errors (403 with "ExceptionResourceNoAccess") no longer trigger JWT refresh loops
|
|
720
|
+
- Proper separation: base class handles HTTP/session, concrete classes handle auth-specific errors
|
|
721
|
+
[Unreleased]: https://github.com/fr0ster/mcp-abap-connection/compare/v2.0.0...HEAD
|
|
722
|
+
[2.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.10.2...v2.0.0
|
|
723
|
+
[1.10.2]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.10.1...v1.10.2
|
|
724
|
+
[1.10.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.10.0...v1.10.1
|
|
725
|
+
[1.10.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.9.1...v1.10.0
|
|
726
|
+
[1.9.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.9.0...v1.9.1
|
|
727
|
+
[1.9.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.7.0...v1.9.0
|
|
728
|
+
[1.7.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.5.1...v1.7.0
|
|
729
|
+
[1.5.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.4.2...v1.5.1
|
|
730
|
+
[1.4.2]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.4.1...v1.4.2
|
|
731
|
+
[1.4.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.4.0...v1.4.1
|
|
732
|
+
[1.4.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.1.0...v1.4.0
|
|
733
|
+
[1.1.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.0.1...v1.1.0
|
|
734
|
+
[1.0.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v1.0.0...v1.0.1
|
|
735
|
+
[1.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.8...v1.0.0
|
|
736
|
+
[0.2.8]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.7...v0.2.8
|
|
737
|
+
[0.2.7]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.6...v0.2.7
|
|
738
|
+
[0.2.6]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.5...v0.2.6
|
|
739
|
+
[0.2.5]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.4...v0.2.5
|
|
740
|
+
[0.2.4]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.3...v0.2.4
|
|
741
|
+
[0.2.3]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.2...v0.2.3
|
|
742
|
+
[0.2.2]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.1...v0.2.2
|
|
743
|
+
[0.2.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.2.0...v0.2.1
|
|
744
|
+
[0.2.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.15...v0.2.0
|
|
745
|
+
[0.1.15]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.14...v0.1.15
|
|
746
|
+
[0.1.14]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.13...v0.1.14
|
|
747
|
+
[0.1.13]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.12...v0.1.13
|
|
748
|
+
[0.1.12]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.11...v0.1.12
|
|
749
|
+
[0.1.11]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.10...v0.1.11
|
|
750
|
+
[0.1.10]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.9...v0.1.10
|
|
751
|
+
[0.1.9]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.8...v0.1.9
|
|
752
|
+
[0.1.8]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.7...v0.1.8
|
|
753
|
+
[0.1.7]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.6...v0.1.7
|
|
754
|
+
[0.1.6]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.5...v0.1.6
|
|
755
|
+
[0.1.5]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.4...v0.1.5
|
|
756
|
+
[0.1.4]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.3...v0.1.4
|
|
757
|
+
[0.1.3]: https://github.com/fr0ster/mcp-abap-connection/compare/v0.1.2...v0.1.3
|
|
758
|
+
[0.1.2]: https://github.com/fr0ster/mcp-abap-connection/releases/tag/v0.1.2
|