@mcp-abap-adt/connection 4.0.0 → 5.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 +274 -1
- package/README.md +60 -30
- package/dist/auth/IAuthProvider.d.ts +84 -0
- package/dist/auth/IAuthProvider.d.ts.map +1 -0
- package/dist/auth/IAuthProvider.js +21 -0
- package/dist/auth/providers.d.ts +95 -0
- package/dist/auth/providers.d.ts.map +1 -0
- package/dist/auth/providers.js +140 -0
- package/dist/connection/AbstractAbapConnection.d.ts +222 -17
- package/dist/connection/AbstractAbapConnection.d.ts.map +1 -1
- package/dist/connection/AbstractAbapConnection.js +555 -31
- package/dist/connection/AdtCloudConnector.d.ts +29 -0
- package/dist/connection/AdtCloudConnector.d.ts.map +1 -0
- package/dist/connection/AdtCloudConnector.js +31 -0
- package/dist/connection/AdtOnPremConnector.d.ts +30 -0
- package/dist/connection/AdtOnPremConnector.d.ts.map +1 -0
- package/dist/connection/AdtOnPremConnector.js +32 -0
- package/dist/connection/BaseAbapConnection.d.ts +7 -1
- package/dist/connection/BaseAbapConnection.d.ts.map +1 -1
- package/dist/connection/BaseAbapConnection.js +7 -1
- package/dist/connection/CertificateAbapConnection.d.ts +11 -1
- package/dist/connection/CertificateAbapConnection.d.ts.map +1 -1
- package/dist/connection/CertificateAbapConnection.js +13 -1
- package/dist/connection/CredentialAbapConnection.d.ts +88 -0
- package/dist/connection/CredentialAbapConnection.d.ts.map +1 -0
- package/dist/connection/CredentialAbapConnection.js +195 -0
- package/dist/connection/JwtAbapConnection.d.ts +23 -7
- package/dist/connection/JwtAbapConnection.d.ts.map +1 -1
- package/dist/connection/JwtAbapConnection.js +26 -8
- package/dist/connection/KerberosAbapConnection.d.ts +9 -1
- package/dist/connection/KerberosAbapConnection.d.ts.map +1 -1
- package/dist/connection/KerberosAbapConnection.js +9 -1
- package/dist/connection/RfcAbapConnection.d.ts +0 -5
- package/dist/connection/RfcAbapConnection.d.ts.map +1 -1
- package/dist/connection/RfcAbapConnection.js +0 -7
- package/dist/connection/SamlAbapConnection.d.ts +7 -1
- package/dist/connection/SamlAbapConnection.d.ts.map +1 -1
- package/dist/connection/SamlAbapConnection.js +7 -1
- package/dist/connection/connectionFactory.d.ts +16 -0
- package/dist/connection/connectionFactory.d.ts.map +1 -1
- package/dist/connection/connectionFactory.js +52 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/session/CloudSecuritySessionStrategy.d.ts +32 -0
- package/dist/session/CloudSecuritySessionStrategy.d.ts.map +1 -0
- package/dist/session/CloudSecuritySessionStrategy.js +135 -0
- package/dist/session/IcfSessionStrategy.d.ts +27 -0
- package/dist/session/IcfSessionStrategy.d.ts.map +1 -0
- package/dist/session/IcfSessionStrategy.js +62 -0
- package/dist/session/SessionLifecycle.d.ts +17 -2
- package/dist/session/SessionLifecycle.d.ts.map +1 -1
- package/dist/session/SessionLifecycle.js +17 -2
- package/dist/session/SessionStrategy.d.ts +86 -0
- package/dist/session/SessionStrategy.d.ts.map +1 -0
- package/dist/session/SessionStrategy.js +33 -0
- package/dist/utils/cookies.d.ts +12 -0
- package/dist/utils/cookies.d.ts.map +1 -0
- package/dist/utils/cookies.js +24 -0
- package/dist/utils/timeouts.d.ts +16 -0
- package/dist/utils/timeouts.d.ts.map +1 -1
- package/dist/utils/timeouts.js +19 -0
- package/docs/INSTALLATION.md +6 -2
- package/docs/MIGRATION-2.0.md +1 -1
- package/docs/MIGRATION-5.0.md +116 -0
- package/docs/STATEFUL_SESSION_GUIDE.md +77 -11
- package/docs/USAGE.md +92 -22
- package/docs/superpowers/specs/2026-08-21-platform-connectors.md +108 -0
- package/package.json +1 -1
package/docs/USAGE.md
CHANGED
|
@@ -36,7 +36,9 @@ const logger = {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
// Create connection (logger is optional)
|
|
39
|
-
const connection = createAbapConnection(config, logger
|
|
39
|
+
const connection = createAbapConnection(config, logger, undefined, undefined, {
|
|
40
|
+
system: 'onprem', // or 'cloud' — said by you, never detected
|
|
41
|
+
});
|
|
40
42
|
// Or without logger:
|
|
41
43
|
// const connection = createAbapConnection(config);
|
|
42
44
|
|
|
@@ -57,14 +59,27 @@ Tearing the session down is `disconnect()`, but it is not on the
|
|
|
57
59
|
`IAbapConnection` type this factory returns — see
|
|
58
60
|
[Session Lifecycle](#session-lifecycle) for where it lives and how to reach it.
|
|
59
61
|
|
|
60
|
-
##
|
|
62
|
+
## Which system, and how you authenticate
|
|
63
|
+
|
|
64
|
+
Two independent choices, and they must stay independent. The connector says
|
|
65
|
+
which SYSTEM you are dialling; the auth provider says how you prove who you
|
|
66
|
+
are. A communication user against ABAP Cloud and a bearer token against an
|
|
67
|
+
on-prem system are both ordinary, and a design where the credential picked the
|
|
68
|
+
system's session mechanism got one of them wrong whichever way it guessed.
|
|
69
|
+
|
|
70
|
+
Nothing is detected. `/sap/bc/adt/core/http/sessions` answers on on-prem too,
|
|
71
|
+
and its `DELETE` there leaves the session open while the platform logoff removes
|
|
72
|
+
it — so asking the server would choose the mechanism that releases nothing.
|
|
61
73
|
|
|
62
74
|
### Basic Authentication (On-Premise)
|
|
63
75
|
|
|
64
76
|
For on-premise SAP systems using basic authentication:
|
|
65
77
|
|
|
66
78
|
```typescript
|
|
67
|
-
import {
|
|
79
|
+
import {
|
|
80
|
+
AdtOnPremConnector,
|
|
81
|
+
BasicAuthProvider,
|
|
82
|
+
} from '@mcp-abap-adt/connection';
|
|
68
83
|
|
|
69
84
|
const config = {
|
|
70
85
|
url: 'https://sap-server.local:8000',
|
|
@@ -74,7 +89,11 @@ const config = {
|
|
|
74
89
|
client: '100',
|
|
75
90
|
};
|
|
76
91
|
|
|
77
|
-
const connection = new
|
|
92
|
+
const connection = new AdtOnPremConnector(
|
|
93
|
+
config,
|
|
94
|
+
new BasicAuthProvider(config.username, config.password),
|
|
95
|
+
logger,
|
|
96
|
+
);
|
|
78
97
|
await connection.connect(); // required: nothing is established implicitly
|
|
79
98
|
```
|
|
80
99
|
|
|
@@ -84,16 +103,25 @@ For SAP BTP ABAP Environment. Token refresh belongs to
|
|
|
84
103
|
`@mcp-abap-adt/auth-broker`; this package only carries the token:
|
|
85
104
|
|
|
86
105
|
```typescript
|
|
87
|
-
import {
|
|
106
|
+
import {
|
|
107
|
+
AdtCloudConnector,
|
|
108
|
+
TokenAuthProvider,
|
|
109
|
+
} from '@mcp-abap-adt/connection';
|
|
88
110
|
|
|
89
111
|
const config = {
|
|
90
112
|
url: 'https://tenant.abap.cloud',
|
|
91
113
|
authType: 'jwt' as const,
|
|
92
|
-
jwtToken: 'eyJhbGciOiJSUzI1NiIs...',
|
|
93
114
|
client: '100', // Optional for cloud
|
|
94
115
|
};
|
|
95
116
|
|
|
96
|
-
|
|
117
|
+
// A bare token works and has no renewal behind it. Hand the provider an
|
|
118
|
+
// ITokenRefresher instead — from @mcp-abap-adt/auth-broker or your own — and it
|
|
119
|
+
// checks expiry and refreshes on its own.
|
|
120
|
+
const connection = new AdtCloudConnector(
|
|
121
|
+
config,
|
|
122
|
+
new TokenAuthProvider('eyJhbGciOiJSUzI1NiIs...'),
|
|
123
|
+
logger,
|
|
124
|
+
);
|
|
97
125
|
await connection.connect(); // required: nothing is established implicitly
|
|
98
126
|
|
|
99
127
|
// Note: Token refresh is handled by @mcp-abap-adt/auth-broker package
|
|
@@ -172,7 +200,9 @@ await connection.makeAdtRequest({
|
|
|
172
200
|
By default, connections are stateless - each request gets fresh cookies and CSRF tokens:
|
|
173
201
|
|
|
174
202
|
```typescript
|
|
175
|
-
const connection = createAbapConnection(config, logger
|
|
203
|
+
const connection = createAbapConnection(config, logger, undefined, undefined, {
|
|
204
|
+
system: 'onprem', // or 'cloud' — said by you, never detected
|
|
205
|
+
});
|
|
176
206
|
await connection.connect();
|
|
177
207
|
|
|
178
208
|
// Each request is independent
|
|
@@ -184,7 +214,9 @@ await connection.makeAdtRequest({ method: 'GET', url: '/sap/bc/adt/discovery' })
|
|
|
184
214
|
Enable stateful session mode for operations requiring consistent session state:
|
|
185
215
|
|
|
186
216
|
```typescript
|
|
187
|
-
const connection = createAbapConnection(config, logger
|
|
217
|
+
const connection = createAbapConnection(config, logger, undefined, undefined, {
|
|
218
|
+
system: 'onprem', // or 'cloud' — said by you, never detected
|
|
219
|
+
});
|
|
188
220
|
await connection.connect();
|
|
189
221
|
|
|
190
222
|
// Enable stateful session mode (adds x-sap-adt-sessiontype: stateful header)
|
|
@@ -242,7 +274,7 @@ implied. Four things follow from it.
|
|
|
242
274
|
> site:
|
|
243
275
|
>
|
|
244
276
|
> ```typescript
|
|
245
|
-
> const conn = new
|
|
277
|
+
> const conn = new AdtOnPremConnector(config, provider, logger);
|
|
246
278
|
> tearDownAfter(conn); // ✅ checked
|
|
247
279
|
> tearDownAfter(new RfcAbapConnection(cfg)); // ✅ compile error, as it should be
|
|
248
280
|
> ```
|
|
@@ -290,9 +322,13 @@ implied. Four things follow from it.
|
|
|
290
322
|
### connect() is required, and it tells the truth
|
|
291
323
|
|
|
292
324
|
```typescript
|
|
293
|
-
import {
|
|
325
|
+
import { AdtOnPremConnector, BasicAuthProvider } from '@mcp-abap-adt/connection';
|
|
294
326
|
|
|
295
|
-
const connection = new
|
|
327
|
+
const connection = new AdtOnPremConnector(
|
|
328
|
+
config,
|
|
329
|
+
new BasicAuthProvider(user, pass),
|
|
330
|
+
logger,
|
|
331
|
+
);
|
|
296
332
|
|
|
297
333
|
await connection.connect(); // establishes the session, or rejects
|
|
298
334
|
connection.isConnected(); // true only while a usable session exists
|
|
@@ -420,7 +456,9 @@ yours.
|
|
|
420
456
|
Session IDs are auto-generated (UUID) when connection is created:
|
|
421
457
|
|
|
422
458
|
```typescript
|
|
423
|
-
const connection = createAbapConnection(config, logger
|
|
459
|
+
const connection = createAbapConnection(config, logger, undefined, undefined, {
|
|
460
|
+
system: 'onprem', // or 'cloud' — said by you, never detected
|
|
461
|
+
});
|
|
424
462
|
console.log(connection.getSessionId()); // e.g., '7f3a8b2c-...'
|
|
425
463
|
|
|
426
464
|
// Or provide your own when creating connection
|
|
@@ -434,7 +472,9 @@ Dynamically switch between stateful and stateless modes:
|
|
|
434
472
|
|
|
435
473
|
```typescript
|
|
436
474
|
// Start in stateless mode (default)
|
|
437
|
-
const connection = createAbapConnection(config, logger
|
|
475
|
+
const connection = createAbapConnection(config, logger, undefined, undefined, {
|
|
476
|
+
system: 'onprem', // or 'cloud' — said by you, never detected
|
|
477
|
+
});
|
|
438
478
|
await connection.connect();
|
|
439
479
|
|
|
440
480
|
// Enable stateful for a series of operations
|
|
@@ -447,14 +487,20 @@ await connection.makeAdtRequest({ method: 'POST', url: '...' });
|
|
|
447
487
|
connection.setSessionType('stateless');
|
|
448
488
|
```
|
|
449
489
|
|
|
450
|
-
###
|
|
490
|
+
### Starting Over
|
|
451
491
|
|
|
452
|
-
|
|
492
|
+
There is no local-only reset. Discarding the cookie does not end the ABAP
|
|
493
|
+
session — the server keeps it until its own timeout, and sessions are limited
|
|
494
|
+
per user — so starting over means telling the server, then connecting again:
|
|
453
495
|
|
|
454
496
|
```typescript
|
|
455
|
-
connection.
|
|
497
|
+
await connection.disconnect(); // ends the session on the server too
|
|
498
|
+
await connection.connect(); // a new one, explicitly
|
|
456
499
|
```
|
|
457
500
|
|
|
501
|
+
A connection that was connected must be disconnected, which is why this belongs
|
|
502
|
+
in a `finally`. `disconnect()` never throws, so it is safe there.
|
|
503
|
+
|
|
458
504
|
## Custom Logging
|
|
459
505
|
|
|
460
506
|
### Using Custom Logger
|
|
@@ -493,7 +539,9 @@ class CustomLogger implements ILogger {
|
|
|
493
539
|
}
|
|
494
540
|
|
|
495
541
|
const logger = new CustomLogger();
|
|
496
|
-
const connection = createAbapConnection(config, logger
|
|
542
|
+
const connection = createAbapConnection(config, logger, undefined, undefined, {
|
|
543
|
+
system: 'onprem', // or 'cloud' — said by you, never detected
|
|
544
|
+
});
|
|
497
545
|
```
|
|
498
546
|
|
|
499
547
|
## Error Handling
|
|
@@ -577,16 +625,38 @@ interface AbapConnection {
|
|
|
577
625
|
}
|
|
578
626
|
```
|
|
579
627
|
|
|
580
|
-
Anything beyond that is **not** on the contract. `
|
|
628
|
+
Anything beyond that is **not** on the contract. `getSessionMode()`
|
|
581
629
|
and the session lifecycle (`disconnect()`, `isConnected()`,
|
|
582
630
|
`getSessionIdentity()`) live on the HTTP
|
|
583
631
|
connection classes; `RfcAbapConnection` has some of them and not others, so
|
|
584
632
|
reach for them through a concrete type rather than through what
|
|
585
633
|
`createAbapConnection()` returns.
|
|
586
634
|
|
|
587
|
-
### `
|
|
635
|
+
### `AdtOnPremConnector` / `AdtCloudConnector`
|
|
636
|
+
|
|
637
|
+
One per system, each handed an auth provider:
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
class AdtOnPremConnector extends CredentialAbapConnection {
|
|
641
|
+
constructor(
|
|
642
|
+
config: SapConfig,
|
|
643
|
+
provider: IAuthProvider,
|
|
644
|
+
logger?: ILogger | null,
|
|
645
|
+
sessionId?: string,
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
// AdtCloudConnector has the same shape.
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
The difference is what each does with the session: on-prem takes it from the
|
|
652
|
+
establishing call and gives it back with the platform's ICF logoff; cloud opens
|
|
653
|
+
one at `/sap/bc/adt/core/http/sessions` and gives it back by `DELETE` on the
|
|
654
|
+
address the server publishes.
|
|
655
|
+
|
|
656
|
+
### `BaseAbapConnection` (Basic Auth) — deprecated
|
|
588
657
|
|
|
589
|
-
|
|
658
|
+
The previous shape, where the class stated the credential. Still works; see
|
|
659
|
+
[Migration to 5.0](./MIGRATION-5.0.md).
|
|
590
660
|
|
|
591
661
|
```typescript
|
|
592
662
|
class BaseAbapConnection extends AbstractAbapConnection {
|
|
@@ -670,7 +740,7 @@ export class CloudSdkAbapConnection {
|
|
|
670
740
|
```
|
|
671
741
|
|
|
672
742
|
|
|
673
|
-
### `JwtAbapConnection` (JWT/OAuth2)
|
|
743
|
+
### `JwtAbapConnection` (JWT/OAuth2) — deprecated
|
|
674
744
|
|
|
675
745
|
For SAP BTP cloud systems. Token refresh is handled by `@mcp-abap-adt/auth-broker`:
|
|
676
746
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Two connectors, one credential contract
|
|
2
|
+
|
|
3
|
+
**Status:** draft, for review
|
|
4
|
+
**Subject:** `AdtOnPremConnector` / `AdtCloudConnector` over a shared base, with authentication passed in rather than inherited.
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
The class you take today states your **credential**, and the session mechanism rides along with it. `JwtAbapConnection` is the only class that overrides `createSessionStrategy()`, so:
|
|
9
|
+
|
|
10
|
+
| the consumer builds | on a **cloud** host | on an **on-prem** host |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `authType: 'jwt'` | ADT session resource — correct | ADT session resource — wrong |
|
|
13
|
+
| `authType: 'basic'` | ICF logoff — wrong | ICF logoff — correct |
|
|
14
|
+
| `authType: 'saml'` | ICF logoff — wrong | correct |
|
|
15
|
+
| `authType: 'certificate'`, `'kerberos'` | ICF logoff — wrong | correct |
|
|
16
|
+
|
|
17
|
+
Both wrong rows are reachable. The cloud trial answers `www-authenticate: Basic`, so a communication user against ABAP Cloud is an ordinary setup; SAML is the usual interactive logon on BTP. And the mirror — JWT against an on-prem system — puts that system on a mechanism it does not use.
|
|
18
|
+
|
|
19
|
+
**The consumer knows which system it is dialling.** It should say so by taking the connector for it, and the credential should be a parameter of that choice rather than the thing making it.
|
|
20
|
+
|
|
21
|
+
### Why not detect it
|
|
22
|
+
|
|
23
|
+
Tried, measured, wrong. `/sap/bc/adt/core/http/sessions` was probed to decide the mechanism; **on-prem answers it too** — 200, a `SAP_SESSIONID`, and a document publishing *both* the session resource and `/sap/public/bc/icf/logoff`. The probe never told the two systems apart; it told whether an endpoint exists, and both have it, so on-prem was silently moved onto the cloud mechanism.
|
|
24
|
+
|
|
25
|
+
Nothing here goes back to asking the server which kind of system it is.
|
|
26
|
+
|
|
27
|
+
## The shape
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
AbstractAbapConnection requests, CSRF, cookies, session lifecycle, admission
|
|
31
|
+
│
|
|
32
|
+
├── AdtOnPremConnector session arrives with the establishing call;
|
|
33
|
+
│ given back with the platform's ICF logoff
|
|
34
|
+
│
|
|
35
|
+
└── AdtCloudConnector session opened at /sap/bc/adt/core/http/sessions
|
|
36
|
+
(`x-sap-security-session: create`,
|
|
37
|
+
`sap-adt-purpose: preflight_logon`);
|
|
38
|
+
given back by DELETE on the address it published
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Both take a **credential** object. The two session strategies already exist and do not change; what changes is who chooses them and how authentication arrives.
|
|
42
|
+
|
|
43
|
+
## The credential contract
|
|
44
|
+
|
|
45
|
+
`ITokenRefresher` and `ITokenProvider` already exist in `@mcp-abap-adt/interfaces` — the first says outright *"Created by AuthBroker for a specific destination. Injected into JwtAbapConnection to enable automatic token refresh."* — and `@mcp-abap-adt/auth-providers` ships twelve implementations. That is the seam to join, not to reinvent.
|
|
46
|
+
|
|
47
|
+
But both are about **tokens**, and only one of the five ways in works that way. Measured, every current class overrides exactly two members, plus a few extras:
|
|
48
|
+
|
|
49
|
+
| | `buildAuthorizationHeader` | `establishSession` | other |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| basic | ✓ | ✓ | — |
|
|
52
|
+
| jwt | ✓ | ✓ | `prepareCredential`, `ensureToken` |
|
|
53
|
+
| saml | ✓ | ✓ | — |
|
|
54
|
+
| certificate | ✓ | ✓ | `getHttpsAgentOptions`, `ensureMaterial` |
|
|
55
|
+
| kerberos | ✓ | ✓ | `fetchCsrfToken` |
|
|
56
|
+
|
|
57
|
+
So the contract is small and is **not** "give me a token":
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
interface IAbapCredential {
|
|
61
|
+
/** Prepare before anything is sent — mint, load, unlock. Optional. */
|
|
62
|
+
prepare?(): Promise<void>;
|
|
63
|
+
/** The Authorization header value, or '' when the credential is not a header. */
|
|
64
|
+
authorizationHeader(): string;
|
|
65
|
+
/** TLS material, for credentials that are a certificate rather than a header. */
|
|
66
|
+
httpsAgentOptions?(): AgentOptions;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
A token provider becomes one implementation of it, wrapping `ITokenRefresher`. Basic wraps a username and password. Certificate returns no header and supplies agent options instead.
|
|
71
|
+
|
|
72
|
+
**Where it lives:** `@mcp-abap-adt/interfaces`, released before the connector consumes it — the standing rule, no local bridge.
|
|
73
|
+
|
|
74
|
+
## The hard part, named
|
|
75
|
+
|
|
76
|
+
`JwtAbapConnection` is 483 lines and **most of it is not authentication.** `renewalInFlight`, the `AsyncLocalStorage` operation scopes, `tokenGeneration` against `recoveredGeneration`, `ensureRecovered`, and the calls to `discardSession()` and `recoverSession()` are about what happens to *the session* when the credential is renewed mid-flight. That is connection business and stays in the base.
|
|
77
|
+
|
|
78
|
+
The split to make:
|
|
79
|
+
|
|
80
|
+
- **credential**: "get me a valid token" → the provider, behind `IAbapCredential`;
|
|
81
|
+
- **connection**: "the credential changed, so the session it built is gone — discard, re-establish, let the request retry once" → the base, unchanged in behaviour.
|
|
82
|
+
|
|
83
|
+
If this line is drawn wrongly the 4.0.0 work is undone, and that work exists because the failures it fixed were subtle: two layered single-flight promises, identity-checked clears, an epoch checked before a retry. **The spec's success condition is that every test from 4.0.0 passes untouched.**
|
|
84
|
+
|
|
85
|
+
## Migration
|
|
86
|
+
|
|
87
|
+
The five current classes stay, deprecated, as thin wrappers: `new JwtAbapConnection(config, logger, sessionId, refresher)` builds `AdtCloudConnector` with a token credential. Nothing published breaks, and `createAbapConnection()` keeps working from `SapConfig` alone.
|
|
88
|
+
|
|
89
|
+
New code takes a connector and hands it a credential.
|
|
90
|
+
|
|
91
|
+
## What this does not do
|
|
92
|
+
|
|
93
|
+
- **No auto-detection**, in any form — see above.
|
|
94
|
+
- **No change to the two session strategies.** They were measured against a live trial and an on-prem system and are not the subject here.
|
|
95
|
+
- **No new auth mechanism.** Only a place for the ones that exist to be passed in.
|
|
96
|
+
- **No dependency on the auth packages.** The connector keeps speaking contracts; consumers supply implementations, as with `IAbapConnection` today.
|
|
97
|
+
|
|
98
|
+
## Open, to settle in review
|
|
99
|
+
|
|
100
|
+
1. **`prepare()` and Kerberos.** SPNEGO deliberately does not prepare early: minting the token sooner changes when the exchange happens, and that path is not production-tested. Does Kerberos keep opting out, or does the contract grow a way to say "prepare late"?
|
|
101
|
+
2. **What `createAbapConnection(config)` does when the config does not say which system it is.** Defaulting to on-prem keeps every existing consumer working and never guesses; refusing is more honest and breaks them. Deprecation-shaped default seems right, but it is a decision.
|
|
102
|
+
3. **Whether `AdtOnPremConnector` should refuse the ADT session resource explicitly** — it exists there and answers, so a future edit could quietly start using it.
|
|
103
|
+
|
|
104
|
+
## How it gets verified
|
|
105
|
+
|
|
106
|
+
- Cloud: from this machine, against the BTP trial — connect, hold a session across stateful requests, disconnect. Already the way the current mechanism was measured.
|
|
107
|
+
- On-prem: not reachable from here. Reviewed and run on the machine that reaches a system, as PR #34 was: strategy `icf`, `lock → PUT` chains, session present, and **no request to the session resource**.
|
|
108
|
+
- Both wrong rows from the table above become tests: a cloud connector with a basic credential must use the ADT session; an on-prem connector with a token credential must not.
|