@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
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An ABAP Cloud system.
|
|
3
|
+
*
|
|
4
|
+
* A session there is a **resource**: asked for at
|
|
5
|
+
* `/sap/bc/adt/core/http/sessions` with `x-sap-security-session: create` and
|
|
6
|
+
* `sap-adt-purpose: preflight_logon`, and given back by `DELETE` on the address
|
|
7
|
+
* the server publishes in the answer. Reproduced from Eclipse ADT 3.60 and
|
|
8
|
+
* measured against a BTP trial: without that request the same connection gets
|
|
9
|
+
* `sap-usercontext` and `sap-XSRF_*` and no session for a lock to be bound to,
|
|
10
|
+
* which is how "cloud issues no SAP_SESSIONID" came to be believed.
|
|
11
|
+
*
|
|
12
|
+
* **Taking this class is the consumer stating which system it is dialling**, and
|
|
13
|
+
* it is the only thing that states it: a communication user against ABAP Cloud
|
|
14
|
+
* gets this mechanism because the caller asked for this connector. Nothing is
|
|
15
|
+
* inferred — not from the credential, not from the host name, not from what the
|
|
16
|
+
* server answers.
|
|
17
|
+
*/
|
|
18
|
+
import type { IAuthProvider } from '../auth/IAuthProvider.js';
|
|
19
|
+
import type { SapConfig } from '../config/sapConfig.js';
|
|
20
|
+
import type { ILogger } from '../logger.js';
|
|
21
|
+
import type { SessionStrategy } from '../session/SessionStrategy.js';
|
|
22
|
+
import { CredentialAbapConnection } from './CredentialAbapConnection.js';
|
|
23
|
+
export declare class AdtCloudConnector extends CredentialAbapConnection {
|
|
24
|
+
constructor(config: SapConfig, credential: IAuthProvider, logger?: ILogger | null, sessionId?: string, options?: {
|
|
25
|
+
skipSessionType?: boolean;
|
|
26
|
+
});
|
|
27
|
+
protected createSessionStrategy(): SessionStrategy;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=AdtCloudConnector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdtCloudConnector.d.ts","sourceRoot":"","sources":["../../src/connection/AdtCloudConnector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,qBAAa,iBAAkB,SAAQ,wBAAwB;gBAE3D,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,aAAa,EACzB,MAAM,GAAE,OAAO,GAAG,IAAW,EAC7B,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE;cAKtB,qBAAqB,IAAI,eAAe;CAG5D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* An ABAP Cloud system.
|
|
4
|
+
*
|
|
5
|
+
* A session there is a **resource**: asked for at
|
|
6
|
+
* `/sap/bc/adt/core/http/sessions` with `x-sap-security-session: create` and
|
|
7
|
+
* `sap-adt-purpose: preflight_logon`, and given back by `DELETE` on the address
|
|
8
|
+
* the server publishes in the answer. Reproduced from Eclipse ADT 3.60 and
|
|
9
|
+
* measured against a BTP trial: without that request the same connection gets
|
|
10
|
+
* `sap-usercontext` and `sap-XSRF_*` and no session for a lock to be bound to,
|
|
11
|
+
* which is how "cloud issues no SAP_SESSIONID" came to be believed.
|
|
12
|
+
*
|
|
13
|
+
* **Taking this class is the consumer stating which system it is dialling**, and
|
|
14
|
+
* it is the only thing that states it: a communication user against ABAP Cloud
|
|
15
|
+
* gets this mechanism because the caller asked for this connector. Nothing is
|
|
16
|
+
* inferred — not from the credential, not from the host name, not from what the
|
|
17
|
+
* server answers.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.AdtCloudConnector = void 0;
|
|
21
|
+
const CloudSecuritySessionStrategy_js_1 = require("../session/CloudSecuritySessionStrategy.js");
|
|
22
|
+
const CredentialAbapConnection_js_1 = require("./CredentialAbapConnection.js");
|
|
23
|
+
class AdtCloudConnector extends CredentialAbapConnection_js_1.CredentialAbapConnection {
|
|
24
|
+
constructor(config, credential, logger = null, sessionId, options) {
|
|
25
|
+
super(config, credential, logger, sessionId, options);
|
|
26
|
+
}
|
|
27
|
+
createSessionStrategy() {
|
|
28
|
+
return new CloudSecuritySessionStrategy_js_1.CloudSecuritySessionStrategy(this.logger);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.AdtCloudConnector = AdtCloudConnector;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An on-prem ABAP system.
|
|
3
|
+
*
|
|
4
|
+
* The session arrives with the establishing call — the logon *is* that call —
|
|
5
|
+
* and the platform's `/sap/public/bc/icf/logoff` is how it is given back. That
|
|
6
|
+
* is what on-prem has always used here, and it does not change.
|
|
7
|
+
*
|
|
8
|
+
* **Taking this class is the consumer stating which system it is dialling.**
|
|
9
|
+
* Nothing is probed and nothing is inferred: `/sap/bc/adt/core/http/sessions` answers on on-prem too —
|
|
10
|
+
* measured on S/4HANA, publishing both the session resource and the ICF logoff
|
|
11
|
+
* in one document — so asking the server tells you an endpoint exists, not
|
|
12
|
+
* which kind of system you reached.
|
|
13
|
+
*
|
|
14
|
+
* The credential is passed in and decides none of this. A bearer token against
|
|
15
|
+
* an on-prem system is ordinary, and it gets this mechanism because the caller
|
|
16
|
+
* asked for this connector — not because of what is in the header, and not
|
|
17
|
+
* because anything worked out where it was pointing.
|
|
18
|
+
*/
|
|
19
|
+
import type { IAuthProvider } from '../auth/IAuthProvider.js';
|
|
20
|
+
import type { SapConfig } from '../config/sapConfig.js';
|
|
21
|
+
import type { ILogger } from '../logger.js';
|
|
22
|
+
import type { SessionStrategy } from '../session/SessionStrategy.js';
|
|
23
|
+
import { CredentialAbapConnection } from './CredentialAbapConnection.js';
|
|
24
|
+
export declare class AdtOnPremConnector extends CredentialAbapConnection {
|
|
25
|
+
constructor(config: SapConfig, credential: IAuthProvider, logger?: ILogger | null, sessionId?: string, options?: {
|
|
26
|
+
skipSessionType?: boolean;
|
|
27
|
+
});
|
|
28
|
+
protected createSessionStrategy(): SessionStrategy;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=AdtOnPremConnector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdtOnPremConnector.d.ts","sourceRoot":"","sources":["../../src/connection/AdtOnPremConnector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,qBAAa,kBAAmB,SAAQ,wBAAwB;gBAE5D,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,aAAa,EACzB,MAAM,GAAE,OAAO,GAAG,IAAW,EAC7B,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE;cAKtB,qBAAqB,IAAI,eAAe;CAG5D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* An on-prem ABAP system.
|
|
4
|
+
*
|
|
5
|
+
* The session arrives with the establishing call — the logon *is* that call —
|
|
6
|
+
* and the platform's `/sap/public/bc/icf/logoff` is how it is given back. That
|
|
7
|
+
* is what on-prem has always used here, and it does not change.
|
|
8
|
+
*
|
|
9
|
+
* **Taking this class is the consumer stating which system it is dialling.**
|
|
10
|
+
* Nothing is probed and nothing is inferred: `/sap/bc/adt/core/http/sessions` answers on on-prem too —
|
|
11
|
+
* measured on S/4HANA, publishing both the session resource and the ICF logoff
|
|
12
|
+
* in one document — so asking the server tells you an endpoint exists, not
|
|
13
|
+
* which kind of system you reached.
|
|
14
|
+
*
|
|
15
|
+
* The credential is passed in and decides none of this. A bearer token against
|
|
16
|
+
* an on-prem system is ordinary, and it gets this mechanism because the caller
|
|
17
|
+
* asked for this connector — not because of what is in the header, and not
|
|
18
|
+
* because anything worked out where it was pointing.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.AdtOnPremConnector = void 0;
|
|
22
|
+
const IcfSessionStrategy_js_1 = require("../session/IcfSessionStrategy.js");
|
|
23
|
+
const CredentialAbapConnection_js_1 = require("./CredentialAbapConnection.js");
|
|
24
|
+
class AdtOnPremConnector extends CredentialAbapConnection_js_1.CredentialAbapConnection {
|
|
25
|
+
constructor(config, credential, logger = null, sessionId, options) {
|
|
26
|
+
super(config, credential, logger, sessionId, options);
|
|
27
|
+
}
|
|
28
|
+
createSessionStrategy() {
|
|
29
|
+
return new IcfSessionStrategy_js_1.IcfSessionStrategy(this.logger);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.AdtOnPremConnector = AdtOnPremConnector;
|
|
@@ -2,7 +2,13 @@ import type { SapConfig } from '../config/sapConfig.js';
|
|
|
2
2
|
import type { ILogger } from '../logger.js';
|
|
3
3
|
import { AbstractAbapConnection } from './AbstractAbapConnection.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* @deprecated The class you take should say which SYSTEM you are dialling,
|
|
6
|
+
* not which credential you hold — a session mechanism that rides along with
|
|
7
|
+
* the credential gets one of them wrong. Use `AdtOnPremConnector` with `BasicAuthProvider`:
|
|
8
|
+
*
|
|
9
|
+
* new AdtOnPremConnector(config, new BasicAuthProvider(user, pass), logger)
|
|
10
|
+
*
|
|
11
|
+
* Kept working, and not removed here: existing consumers are unaffected.
|
|
6
12
|
*/
|
|
7
13
|
export declare class BaseAbapConnection extends AbstractAbapConnection {
|
|
8
14
|
constructor(config: SapConfig, logger?: ILogger | null, sessionId?: string, options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/BaseAbapConnection.ts"],"names":[],"mappings":"AACA,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
|
|
1
|
+
{"version":3,"file":"BaseAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/BaseAbapConnection.ts"],"names":[],"mappings":"AACA,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;;;;;;;;GAQG;AACH,qBAAa,kBAAmB,SAAQ,sBAAsB;gBAE1D,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE;IAMzC;;;OAGG;IACH;;;OAGG;cACa,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6CjD,SAAS,CAAC,wBAAwB,IAAI,MAAM;IAU5C,OAAO,CAAC,MAAM,CAAC,cAAc;CAmB9B"}
|
|
@@ -4,7 +4,13 @@ exports.BaseAbapConnection = void 0;
|
|
|
4
4
|
const axios_1 = require("axios");
|
|
5
5
|
const AbstractAbapConnection_js_1 = require("./AbstractAbapConnection.js");
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* @deprecated The class you take should say which SYSTEM you are dialling,
|
|
8
|
+
* not which credential you hold — a session mechanism that rides along with
|
|
9
|
+
* the credential gets one of them wrong. Use `AdtOnPremConnector` with `BasicAuthProvider`:
|
|
10
|
+
*
|
|
11
|
+
* new AdtOnPremConnector(config, new BasicAuthProvider(user, pass), logger)
|
|
12
|
+
*
|
|
13
|
+
* Kept working, and not removed here: existing consumers are unaffected.
|
|
8
14
|
*/
|
|
9
15
|
class BaseAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnection {
|
|
10
16
|
constructor(config, logger, sessionId, options) {
|
|
@@ -3,7 +3,15 @@ import type { ICertificateMaterialLoader } from '@mcp-abap-adt/interfaces';
|
|
|
3
3
|
import type { SapConfig } from '../config/sapConfig.js';
|
|
4
4
|
import type { ILogger } from '../logger.js';
|
|
5
5
|
import { AbstractAbapConnection } from './AbstractAbapConnection.js';
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated The class you take should say which SYSTEM you are dialling,
|
|
8
|
+
* not which credential you hold — a session mechanism that rides along with
|
|
9
|
+
* the credential gets one of them wrong. Use `AdtOnPremConnector` with `CertificateAuthProvider`:
|
|
10
|
+
*
|
|
11
|
+
* new AdtOnPremConnector(config, new CertificateAuthProvider(loader, config), logger)
|
|
12
|
+
*
|
|
13
|
+
* Kept working, and not removed here: existing consumers are unaffected.
|
|
14
|
+
*/
|
|
7
15
|
export declare class CertificateAbapConnection extends AbstractAbapConnection {
|
|
8
16
|
private loader;
|
|
9
17
|
private material;
|
|
@@ -18,6 +26,8 @@ export declare class CertificateAbapConnection extends AbstractAbapConnection {
|
|
|
18
26
|
* Establishes the session for this auth type. Called by
|
|
19
27
|
* AbstractAbapConnection.connect(), which owns the lifecycle around it.
|
|
20
28
|
*/
|
|
29
|
+
/** The material has to be loaded before anything is sent, preflight included. */
|
|
30
|
+
protected prepareCredential(): Promise<void>;
|
|
21
31
|
protected establishSession(): Promise<void>;
|
|
22
32
|
protected getHttpsAgentOptions(): AgentOptions;
|
|
23
33
|
protected buildAuthorizationHeader(): string;
|
|
@@ -1 +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
|
|
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;;;;;;;;GAQG;AACH,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;IACH;;;OAGG;IACH,iFAAiF;cACxD,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;cAI3C,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BjD,SAAS,CAAC,oBAAoB,IAAI,YAAY;IAU9C,SAAS,CAAC,wBAAwB,IAAI,MAAM;CAG7C"}
|
|
@@ -4,7 +4,15 @@ exports.CertificateAbapConnection = void 0;
|
|
|
4
4
|
const axios_1 = require("axios");
|
|
5
5
|
const FileCertificateMaterialLoader_js_1 = require("../auth/FileCertificateMaterialLoader.js");
|
|
6
6
|
const AbstractAbapConnection_js_1 = require("./AbstractAbapConnection.js");
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated The class you take should say which SYSTEM you are dialling,
|
|
9
|
+
* not which credential you hold — a session mechanism that rides along with
|
|
10
|
+
* the credential gets one of them wrong. Use `AdtOnPremConnector` with `CertificateAuthProvider`:
|
|
11
|
+
*
|
|
12
|
+
* new AdtOnPremConnector(config, new CertificateAuthProvider(loader, config), logger)
|
|
13
|
+
*
|
|
14
|
+
* Kept working, and not removed here: existing consumers are unaffected.
|
|
15
|
+
*/
|
|
8
16
|
class CertificateAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnection {
|
|
9
17
|
loader;
|
|
10
18
|
material = null;
|
|
@@ -42,6 +50,10 @@ class CertificateAbapConnection extends AbstractAbapConnection_js_1.AbstractAbap
|
|
|
42
50
|
* Establishes the session for this auth type. Called by
|
|
43
51
|
* AbstractAbapConnection.connect(), which owns the lifecycle around it.
|
|
44
52
|
*/
|
|
53
|
+
/** The material has to be loaded before anything is sent, preflight included. */
|
|
54
|
+
async prepareCredential() {
|
|
55
|
+
await this.ensureMaterial();
|
|
56
|
+
}
|
|
45
57
|
async establishSession() {
|
|
46
58
|
await this.ensureMaterial();
|
|
47
59
|
const baseUrl = await this.getBaseUrl();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A connection whose authentication is passed in.
|
|
3
|
+
*
|
|
4
|
+
* The shared half of the two platform connectors, and the reason the split is
|
|
5
|
+
* possible at all: `establishSession()` was measured to be the same work in
|
|
6
|
+
* every one of the five auth classes — fetch a CSRF token from
|
|
7
|
+
* `/sap/bc/adt/discovery`, keep it, tolerate a failure — with the only
|
|
8
|
+
* per-credential part being a step before it. That step is `prepare()`.
|
|
9
|
+
*
|
|
10
|
+
* So this owns the establishing call, and the credential contributes three
|
|
11
|
+
* things at most: what to prepare, what header to send, and what TLS material
|
|
12
|
+
* to present. Which system this is talking to was stated by the caller when it
|
|
13
|
+
* chose the subclass, and is never worked out here.
|
|
14
|
+
*/
|
|
15
|
+
import type { AgentOptions } from 'node:https';
|
|
16
|
+
import type { IAbapRequestOptions, IAdtResponse } from '@mcp-abap-adt/interfaces';
|
|
17
|
+
import type { IAuthProvider } from '../auth/IAuthProvider.js';
|
|
18
|
+
import type { SapConfig } from '../config/sapConfig.js';
|
|
19
|
+
import type { ILogger } from '../logger.js';
|
|
20
|
+
import { AbstractAbapConnection } from './AbstractAbapConnection.js';
|
|
21
|
+
export declare abstract class CredentialAbapConnection extends AbstractAbapConnection {
|
|
22
|
+
protected readonly credential: IAuthProvider;
|
|
23
|
+
constructor(config: SapConfig, credential: IAuthProvider, logger?: ILogger | null, sessionId?: string, options?: {
|
|
24
|
+
skipSessionType?: boolean;
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Whatever the credential needs before the first request goes out.
|
|
28
|
+
*
|
|
29
|
+
* Runs before the preflight, not inside the establishing call: building the
|
|
30
|
+
* transport reads the TLS options, and a certificate whose material had not
|
|
31
|
+
* been loaded yet rejected the connect while the argument was still being
|
|
32
|
+
* evaluated — outside every catch, with no request sent.
|
|
33
|
+
*/
|
|
34
|
+
/** The header last put on the wire, so a change can be seen. */
|
|
35
|
+
private lastAuthorization;
|
|
36
|
+
private credentialRenewal?;
|
|
37
|
+
protected prepareCredential(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Nothing here: the header is asked for asynchronously in `getAuthHeaders()`,
|
|
40
|
+
* because a provider can renew behind the call and a synchronous read would
|
|
41
|
+
* have to hold what it returned. The base's abstract member is satisfied and
|
|
42
|
+
* unused.
|
|
43
|
+
*/
|
|
44
|
+
protected buildAuthorizationHeader(): string;
|
|
45
|
+
/**
|
|
46
|
+
* The credential's cookies travel with its header.
|
|
47
|
+
*
|
|
48
|
+
* On every path, not only on ordinary requests: a SAML session that is not
|
|
49
|
+
* presented to the session preflight and the establishing call is a session
|
|
50
|
+
* the server never sees us in.
|
|
51
|
+
*/
|
|
52
|
+
getAuthHeaders(): Promise<Record<string, string>>;
|
|
53
|
+
protected getHttpsAgentOptions(): AgentOptions;
|
|
54
|
+
/**
|
|
55
|
+
* One retry, and only when the credential actually changed.
|
|
56
|
+
*
|
|
57
|
+
* A provider renews on its own — `BaseTokenProvider` checks expiry and
|
|
58
|
+
* refreshes before answering — so a 401 has two very different causes, and
|
|
59
|
+
* asking again tells them apart. A different answer means the token was
|
|
60
|
+
* stale: the ABAP session built on the old one is dead, so it is rebuilt and
|
|
61
|
+
* the request goes once more. The same answer means the server refused these
|
|
62
|
+
* credentials, and repeating them would only ask a second time.
|
|
63
|
+
*
|
|
64
|
+
* This is why no renewal strategy is injected. The provider owns "get me a
|
|
65
|
+
* valid credential"; what is left is "the credential changed, so the session
|
|
66
|
+
* is gone", which belongs to whoever owns the session and cannot be done from
|
|
67
|
+
* outside it.
|
|
68
|
+
*/
|
|
69
|
+
makeAdtRequest<T = any, D = any>(options: IAbapRequestOptions): Promise<IAdtResponse<T, D>>;
|
|
70
|
+
/**
|
|
71
|
+
* Ask the provider again; if it answers differently, rebuild the session.
|
|
72
|
+
*
|
|
73
|
+
* Single-flight, because concurrent operations meet the same 401 at the same
|
|
74
|
+
* moment and the session must be rebuilt once, not once per request in
|
|
75
|
+
* flight. Everyone joins the first one and gets its verdict.
|
|
76
|
+
*/
|
|
77
|
+
private rebuiltAfterCredentialChange;
|
|
78
|
+
/**
|
|
79
|
+
* The establishing call, shared because it always was.
|
|
80
|
+
*
|
|
81
|
+
* Failure is a warning rather than a throw, as it has been: the first request
|
|
82
|
+
* retries it, and a system that answers the discovery call badly may still
|
|
83
|
+
* answer everything else. What decides whether the connection is usable is
|
|
84
|
+
* the session check that follows, not this.
|
|
85
|
+
*/
|
|
86
|
+
protected establishSession(): Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=CredentialAbapConnection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CredentialAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/CredentialAbapConnection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACb,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,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;AASrE,8BAAsB,wBAAyB,SAAQ,sBAAsB;IAGzE,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,aAAa;gBAD5C,MAAM,EAAE,SAAS,EACE,UAAU,EAAE,aAAa,EAC5C,MAAM,GAAE,OAAO,GAAG,IAAW,EAC7B,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE;IAKzC;;;;;;;OAOG;IACH,gEAAgE;IAChE,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,iBAAiB,CAAC,CAAmB;cAEpB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3D;;;;;OAKG;IACH,SAAS,CAAC,wBAAwB,IAAI,MAAM;IAI5C;;;;;;OAMG;IACY,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;cAkB7C,oBAAoB,IAAI,YAAY;IAMvD;;;;;;;;;;;;;;OAcG;IAEY,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAC5C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAwB9B;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IAqCpC;;;;;;;OAOG;cACa,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CA4BlD"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A connection whose authentication is passed in.
|
|
4
|
+
*
|
|
5
|
+
* The shared half of the two platform connectors, and the reason the split is
|
|
6
|
+
* possible at all: `establishSession()` was measured to be the same work in
|
|
7
|
+
* every one of the five auth classes — fetch a CSRF token from
|
|
8
|
+
* `/sap/bc/adt/discovery`, keep it, tolerate a failure — with the only
|
|
9
|
+
* per-credential part being a step before it. That step is `prepare()`.
|
|
10
|
+
*
|
|
11
|
+
* So this owns the establishing call, and the credential contributes three
|
|
12
|
+
* things at most: what to prepare, what header to send, and what TLS material
|
|
13
|
+
* to present. Which system this is talking to was stated by the caller when it
|
|
14
|
+
* chose the subclass, and is never worked out here.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.CredentialAbapConnection = void 0;
|
|
18
|
+
const axios_1 = require("axios");
|
|
19
|
+
const AbstractAbapConnection_js_1 = require("./AbstractAbapConnection.js");
|
|
20
|
+
/** A 401 from the server, whatever transport shape it arrives in. */
|
|
21
|
+
function isUnauthorized(error) {
|
|
22
|
+
const status = error?.response
|
|
23
|
+
?.status;
|
|
24
|
+
return status === 401;
|
|
25
|
+
}
|
|
26
|
+
class CredentialAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnection {
|
|
27
|
+
credential;
|
|
28
|
+
constructor(config, credential, logger = null, sessionId, options) {
|
|
29
|
+
super(config, logger, sessionId, options);
|
|
30
|
+
this.credential = credential;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Whatever the credential needs before the first request goes out.
|
|
34
|
+
*
|
|
35
|
+
* Runs before the preflight, not inside the establishing call: building the
|
|
36
|
+
* transport reads the TLS options, and a certificate whose material had not
|
|
37
|
+
* been loaded yet rejected the connect while the argument was still being
|
|
38
|
+
* evaluated — outside every catch, with no request sent.
|
|
39
|
+
*/
|
|
40
|
+
/** The header last put on the wire, so a change can be seen. */
|
|
41
|
+
lastAuthorization = '';
|
|
42
|
+
credentialRenewal;
|
|
43
|
+
async prepareCredential() {
|
|
44
|
+
await this.credential.prepare?.();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Nothing here: the header is asked for asynchronously in `getAuthHeaders()`,
|
|
48
|
+
* because a provider can renew behind the call and a synchronous read would
|
|
49
|
+
* have to hold what it returned. The base's abstract member is satisfied and
|
|
50
|
+
* unused.
|
|
51
|
+
*/
|
|
52
|
+
buildAuthorizationHeader() {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The credential's cookies travel with its header.
|
|
57
|
+
*
|
|
58
|
+
* On every path, not only on ordinary requests: a SAML session that is not
|
|
59
|
+
* presented to the session preflight and the establishing call is a session
|
|
60
|
+
* the server never sees us in.
|
|
61
|
+
*/
|
|
62
|
+
async getAuthHeaders() {
|
|
63
|
+
const headers = await super.getAuthHeaders();
|
|
64
|
+
// Asked now, not kept: a token provider renews behind this call, and a
|
|
65
|
+
// value held from establishment would be the stale one.
|
|
66
|
+
const authorization = await this.credential.authorizationHeader();
|
|
67
|
+
if (authorization) {
|
|
68
|
+
headers.Authorization = authorization;
|
|
69
|
+
this.lastAuthorization = authorization;
|
|
70
|
+
}
|
|
71
|
+
const cookies = this.credential.cookies?.();
|
|
72
|
+
if (cookies) {
|
|
73
|
+
headers.Cookie = cookies;
|
|
74
|
+
}
|
|
75
|
+
return headers;
|
|
76
|
+
}
|
|
77
|
+
getHttpsAgentOptions() {
|
|
78
|
+
return (this.credential.httpsAgentOptions?.() ?? super.getHttpsAgentOptions());
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* One retry, and only when the credential actually changed.
|
|
82
|
+
*
|
|
83
|
+
* A provider renews on its own — `BaseTokenProvider` checks expiry and
|
|
84
|
+
* refreshes before answering — so a 401 has two very different causes, and
|
|
85
|
+
* asking again tells them apart. A different answer means the token was
|
|
86
|
+
* stale: the ABAP session built on the old one is dead, so it is rebuilt and
|
|
87
|
+
* the request goes once more. The same answer means the server refused these
|
|
88
|
+
* credentials, and repeating them would only ask a second time.
|
|
89
|
+
*
|
|
90
|
+
* This is why no renewal strategy is injected. The provider owns "get me a
|
|
91
|
+
* valid credential"; what is left is "the credential changed, so the session
|
|
92
|
+
* is gone", which belongs to whoever owns the session and cannot be done from
|
|
93
|
+
* outside it.
|
|
94
|
+
*/
|
|
95
|
+
// biome-ignore lint/suspicious/noExplicitAny: matches the base signature exactly
|
|
96
|
+
async makeAdtRequest(options) {
|
|
97
|
+
// Which session this request is going out on. A 401 that comes back after
|
|
98
|
+
// the session has already been replaced says nothing about the credential:
|
|
99
|
+
// it was answered by a server we are no longer talking to.
|
|
100
|
+
const sentOn = this.sessionGeneration;
|
|
101
|
+
try {
|
|
102
|
+
return await super.makeAdtRequest(options);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (!isUnauthorized(error))
|
|
106
|
+
throw error;
|
|
107
|
+
if (!(await this.rebuiltAfterCredentialChange(sentOn)))
|
|
108
|
+
throw error;
|
|
109
|
+
// Exactly once, and to `super` deliberately: reaching for `this` would
|
|
110
|
+
// re-enter this method, and a provider that answers differently every
|
|
111
|
+
// time — a broken refresher, or a server refusing whatever it is given —
|
|
112
|
+
// would look like "the credential changed" forever.
|
|
113
|
+
//
|
|
114
|
+
// A test pins the request count at two, but it does NOT distinguish the
|
|
115
|
+
// two forms: swapping `super` for `this` leaves the suite green, and why
|
|
116
|
+
// it does not then recurse is unexplained. Treat this line as guarded by
|
|
117
|
+
// review, not by the suite.
|
|
118
|
+
return await super.makeAdtRequest(options);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Ask the provider again; if it answers differently, rebuild the session.
|
|
123
|
+
*
|
|
124
|
+
* Single-flight, because concurrent operations meet the same 401 at the same
|
|
125
|
+
* moment and the session must be rebuilt once, not once per request in
|
|
126
|
+
* flight. Everyone joins the first one and gets its verdict.
|
|
127
|
+
*/
|
|
128
|
+
rebuiltAfterCredentialChange(sentOn) {
|
|
129
|
+
if (this.credentialRenewal)
|
|
130
|
+
return this.credentialRenewal;
|
|
131
|
+
const inFlight = (async () => {
|
|
132
|
+
// Somebody else already rebuilt while this request was in flight, so this
|
|
133
|
+
// refusal was answered by a session that no longer exists and says
|
|
134
|
+
// nothing about the credential in use now. Retry on the new one; renewing
|
|
135
|
+
// again would force a second refresh and tear down a healthy session —
|
|
136
|
+
// which is what comparing against a connection-wide "last header" did,
|
|
137
|
+
// since by then that header was the NEW one.
|
|
138
|
+
if (this.sessionGeneration !== sentOn)
|
|
139
|
+
return true;
|
|
140
|
+
const before = this.lastAuthorization;
|
|
141
|
+
// Tell the credential its last answer was refused BEFORE asking again.
|
|
142
|
+
// Asking alone is not enough: a token provider returns the cached token
|
|
143
|
+
// while it believes it is valid, which after a 401 is precisely what it
|
|
144
|
+
// wrongly believes.
|
|
145
|
+
await this.credential.renew?.();
|
|
146
|
+
const now = await this.credential.authorizationHeader();
|
|
147
|
+
if (!now || now === before)
|
|
148
|
+
return false;
|
|
149
|
+
this.logger?.debug('The credential changed after a 401; the session built on the old one is gone. Rebuilding.');
|
|
150
|
+
const baseline = this.teardownEpoch;
|
|
151
|
+
this.discardSession();
|
|
152
|
+
await this.recoverSession(baseline);
|
|
153
|
+
return true;
|
|
154
|
+
})().finally(() => {
|
|
155
|
+
if (this.credentialRenewal === inFlight) {
|
|
156
|
+
this.credentialRenewal = undefined;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
this.credentialRenewal = inFlight;
|
|
160
|
+
return inFlight;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* The establishing call, shared because it always was.
|
|
164
|
+
*
|
|
165
|
+
* Failure is a warning rather than a throw, as it has been: the first request
|
|
166
|
+
* retries it, and a system that answers the discovery call badly may still
|
|
167
|
+
* answer everything else. What decides whether the connection is usable is
|
|
168
|
+
* the session check that follows, not this.
|
|
169
|
+
*/
|
|
170
|
+
async establishSession() {
|
|
171
|
+
const baseUrl = await this.getBaseUrl();
|
|
172
|
+
const discoveryUrl = `${baseUrl}/sap/bc/adt/discovery`;
|
|
173
|
+
try {
|
|
174
|
+
const token = this.credential.fetchCsrfToken
|
|
175
|
+
? await this.credential.fetchCsrfToken(discoveryUrl)
|
|
176
|
+
: await this.fetchCsrfToken(discoveryUrl);
|
|
177
|
+
this.setCsrfToken(token);
|
|
178
|
+
this.logger?.debug('Connected', {
|
|
179
|
+
credential: this.credential.kind,
|
|
180
|
+
hasCsrfToken: !!this.getCsrfToken(),
|
|
181
|
+
hasCookies: !!this.getCookies(),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
this.logger?.warn(`Could not establish upfront (${this.credential.kind}): ${error instanceof Error ? error.message : String(error)}. The first request will retry.`);
|
|
186
|
+
// A rejecting response can still carry the cookies that matter; they are
|
|
187
|
+
// taken by fetchCsrfToken itself, so nothing is read out of the error
|
|
188
|
+
// here beyond saying whether any arrived.
|
|
189
|
+
if (error instanceof axios_1.AxiosError && error.response?.headers) {
|
|
190
|
+
this.logger?.debug(`Cookies after a failed establishment: ${this.getCookies() ? 'present' : 'none'}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
exports.CredentialAbapConnection = CredentialAbapConnection;
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { type IAdtResponse, type ITokenRefresher } from '@mcp-abap-adt/interfaces';
|
|
2
2
|
import type { SapConfig } from '../config/sapConfig.js';
|
|
3
3
|
import type { ILogger } from '../logger.js';
|
|
4
|
+
import type { SessionStrategy } from '../session/SessionStrategy.js';
|
|
4
5
|
import type { AbapRequestOptions } from './AbapConnection.js';
|
|
5
6
|
import { AbstractAbapConnection } from './AbstractAbapConnection.js';
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* The class you take should say which SYSTEM you are dialling, not which
|
|
9
|
+
* credential you hold — a session mechanism that rides along with the
|
|
10
|
+
* credential gets one of them wrong. `AdtCloudConnector` and
|
|
11
|
+
* `AdtOnPremConnector` are how that is said.
|
|
8
12
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* **This class is NOT deprecated yet, and must not be replaced by
|
|
14
|
+
* `AdtCloudConnector` + `TokenAuthProvider`.** What it does beyond
|
|
15
|
+
* authenticating has not moved: a 401 caught mid-operation, one refresh shared
|
|
16
|
+
* by every operation in flight, the session rebuilt behind it, generation
|
|
17
|
+
* fencing so a dead session's response cannot land, and the request retried
|
|
18
|
+
* once. A `TokenAuthProvider` fetches a token at establishment and nothing
|
|
19
|
+
* after it, so swapping today trades all of that for a connection that dies on
|
|
20
|
+
* the first expiry.
|
|
21
|
+
*
|
|
22
|
+
* Use this class for JWT until that machinery moves; the split is the
|
|
23
|
+
* platform-connectors spec's next step.
|
|
15
24
|
*/
|
|
16
25
|
export declare class JwtAbapConnection extends AbstractAbapConnection {
|
|
17
26
|
private tokenRefresher?;
|
|
@@ -97,6 +106,13 @@ export declare class JwtAbapConnection extends AbstractAbapConnection {
|
|
|
97
106
|
* Establishes the session for this auth type. Called by
|
|
98
107
|
* AbstractAbapConnection.connect(), which owns the lifecycle around it.
|
|
99
108
|
*/
|
|
109
|
+
/**
|
|
110
|
+
* Cloud manages sessions through ADT: a session resource is opened at
|
|
111
|
+
* `/sap/bc/adt/core/http/sessions` and given back by `DELETE` on the address
|
|
112
|
+
* the server publishes. This is the one connection that does it — on-prem
|
|
113
|
+
* keeps the platform's ICF logoff, which is what it has always used.
|
|
114
|
+
*/
|
|
115
|
+
protected createSessionStrategy(): SessionStrategy;
|
|
100
116
|
protected establishSession(): Promise<void>;
|
|
101
117
|
/**
|
|
102
118
|
* Override makeAdtRequest to handle JWT auth errors with automatic token refresh
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JwtAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/JwtAbapConnection.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"JwtAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/JwtAbapConnection.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAuBrE;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAkB;IACzC,OAAO,CAAC,YAAY,CAAS;IAE7B,6DAA6D;IAC7D,OAAO,CAAC,eAAe,CAAK;IAE5B,0EAA0E;IAC1E,OAAO,CAAC,oBAAoB,CAAC,CAAmB;IAEhD;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB,CAAK;IAEhC;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe,CAAC,CAAmB;IAE3C;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2C;gBAGvE,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,eAAe;IAWlC,SAAS,CAAC,wBAAwB,IAAI,MAAM;IAW5C;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAc1B,0EAA0E;IAC1E,OAAO,CAAC,eAAe;IASvB;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;YAsBV,mBAAmB;IAoBjC;;OAEG;IACH,OAAO,CAAC,eAAe;YAiBT,cAAc;IAwB5B;;;;OAIG;YACW,eAAe;IAyB7B;;;OAGG;IACH;;;;;OAKG;cACgB,qBAAqB,IAAI,eAAe;cAI3C,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BjD;;OAEG;IACG,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EACnC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAKhB,cAAc;IA8D5B;;OAEG;cACa,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAgC,EAC5C,UAAU,GAAE,MAAgC;IAC5C,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;YASJ,gBAAgB;IAkD9B,OAAO,CAAC,MAAM,CAAC,cAAc;CAa9B"}
|