arc-1 0.1.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/LICENSE +21 -0
- package/README.md +222 -0
- package/bin/arc1.js +12 -0
- package/dist/adt/btp.d.ts +122 -0
- package/dist/adt/btp.d.ts.map +1 -0
- package/dist/adt/btp.js +392 -0
- package/dist/adt/btp.js.map +1 -0
- package/dist/adt/client.d.ts +89 -0
- package/dist/adt/client.d.ts.map +1 -0
- package/dist/adt/client.js +208 -0
- package/dist/adt/client.js.map +1 -0
- package/dist/adt/codeintel.d.ts +38 -0
- package/dist/adt/codeintel.d.ts.map +1 -0
- package/dist/adt/codeintel.js +61 -0
- package/dist/adt/codeintel.js.map +1 -0
- package/dist/adt/config.d.ts +65 -0
- package/dist/adt/config.d.ts.map +1 -0
- package/dist/adt/config.js +35 -0
- package/dist/adt/config.js.map +1 -0
- package/dist/adt/cookies.d.ts +27 -0
- package/dist/adt/cookies.d.ts.map +1 -0
- package/dist/adt/cookies.js +67 -0
- package/dist/adt/cookies.js.map +1 -0
- package/dist/adt/crud.d.ts +35 -0
- package/dist/adt/crud.d.ts.map +1 -0
- package/dist/adt/crud.js +87 -0
- package/dist/adt/crud.js.map +1 -0
- package/dist/adt/devtools.d.ts +32 -0
- package/dist/adt/devtools.d.ts.map +1 -0
- package/dist/adt/devtools.js +154 -0
- package/dist/adt/devtools.js.map +1 -0
- package/dist/adt/errors.d.ts +49 -0
- package/dist/adt/errors.d.ts.map +1 -0
- package/dist/adt/errors.js +80 -0
- package/dist/adt/errors.js.map +1 -0
- package/dist/adt/features.d.ts +44 -0
- package/dist/adt/features.d.ts.map +1 -0
- package/dist/adt/features.js +173 -0
- package/dist/adt/features.js.map +1 -0
- package/dist/adt/http.d.ts +116 -0
- package/dist/adt/http.d.ts.map +1 -0
- package/dist/adt/http.js +374 -0
- package/dist/adt/http.js.map +1 -0
- package/dist/adt/safety.d.ts +70 -0
- package/dist/adt/safety.d.ts.map +1 -0
- package/dist/adt/safety.js +222 -0
- package/dist/adt/safety.js.map +1 -0
- package/dist/adt/transport.d.ts +18 -0
- package/dist/adt/transport.d.ts.map +1 -0
- package/dist/adt/transport.js +66 -0
- package/dist/adt/transport.js.map +1 -0
- package/dist/adt/types.d.ts +91 -0
- package/dist/adt/types.d.ts.map +1 -0
- package/dist/adt/types.js +9 -0
- package/dist/adt/types.js.map +1 -0
- package/dist/adt/xml-parser.d.ts +109 -0
- package/dist/adt/xml-parser.d.ts.map +1 -0
- package/dist/adt/xml-parser.js +283 -0
- package/dist/adt/xml-parser.js.map +1 -0
- package/dist/cache/cache.d.ts +61 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +14 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/memory.d.ts +25 -0
- package/dist/cache/memory.d.ts.map +1 -0
- package/dist/cache/memory.js +69 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/sqlite.d.ts +26 -0
- package/dist/cache/sqlite.d.ts.map +1 -0
- package/dist/cache/sqlite.js +130 -0
- package/dist/cache/sqlite.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +101 -0
- package/dist/cli.js.map +1 -0
- package/dist/context/compressor.d.ts +33 -0
- package/dist/context/compressor.d.ts.map +1 -0
- package/dist/context/compressor.js +208 -0
- package/dist/context/compressor.js.map +1 -0
- package/dist/context/contract.d.ts +14 -0
- package/dist/context/contract.d.ts.map +1 -0
- package/dist/context/contract.js +202 -0
- package/dist/context/contract.js.map +1 -0
- package/dist/context/deps.d.ts +32 -0
- package/dist/context/deps.d.ts.map +1 -0
- package/dist/context/deps.js +240 -0
- package/dist/context/deps.js.map +1 -0
- package/dist/context/types.d.ts +56 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +10 -0
- package/dist/context/types.js.map +1 -0
- package/dist/handlers/intent.d.ts +46 -0
- package/dist/handlers/intent.d.ts.map +1 -0
- package/dist/handlers/intent.js +539 -0
- package/dist/handlers/intent.js.map +1 -0
- package/dist/handlers/tools.d.ts +21 -0
- package/dist/handlers/tools.d.ts.map +1 -0
- package/dist/handlers/tools.js +260 -0
- package/dist/handlers/tools.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/lint.d.ts +35 -0
- package/dist/lint/lint.d.ts.map +1 -0
- package/dist/lint/lint.js +67 -0
- package/dist/lint/lint.js.map +1 -0
- package/dist/server/audit.d.ts +96 -0
- package/dist/server/audit.d.ts.map +1 -0
- package/dist/server/audit.js +27 -0
- package/dist/server/audit.js.map +1 -0
- package/dist/server/config.d.ts +19 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +101 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/context.d.ts +20 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +20 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/elicit.d.ts +43 -0
- package/dist/server/elicit.d.ts.map +1 -0
- package/dist/server/elicit.js +183 -0
- package/dist/server/elicit.js.map +1 -0
- package/dist/server/http.d.ts +34 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +328 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/logger.d.ts +57 -0
- package/dist/server/logger.d.ts.map +1 -0
- package/dist/server/logger.js +129 -0
- package/dist/server/logger.js.map +1 -0
- package/dist/server/server.d.ts +25 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +307 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/sinks/btp-auditlog.d.ts +48 -0
- package/dist/server/sinks/btp-auditlog.d.ts.map +1 -0
- package/dist/server/sinks/btp-auditlog.js +232 -0
- package/dist/server/sinks/btp-auditlog.js.map +1 -0
- package/dist/server/sinks/file.d.ts +22 -0
- package/dist/server/sinks/file.d.ts.map +1 -0
- package/dist/server/sinks/file.js +59 -0
- package/dist/server/sinks/file.js.map +1 -0
- package/dist/server/sinks/stderr.d.ts +19 -0
- package/dist/server/sinks/stderr.d.ts.map +1 -0
- package/dist/server/sinks/stderr.js +63 -0
- package/dist/server/sinks/stderr.js.map +1 -0
- package/dist/server/sinks/types.d.ts +14 -0
- package/dist/server/sinks/types.d.ts.map +1 -0
- package/dist/server/sinks/types.js +8 -0
- package/dist/server/sinks/types.js.map +1 -0
- package/dist/server/types.d.ts +54 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +42 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/xsuaa.d.ts +77 -0
- package/dist/server/xsuaa.d.ts.map +1 -0
- package/dist/server/xsuaa.js +364 -0
- package/dist/server/xsuaa.js.map +1 -0
- package/package.json +66 -0
package/dist/adt/btp.js
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BTP Destination Service integration for ARC-1.
|
|
3
|
+
*
|
|
4
|
+
* When running on SAP BTP Cloud Foundry, this module:
|
|
5
|
+
* 1. Parses VCAP_SERVICES to extract service binding credentials
|
|
6
|
+
* 2. Fetches SAP connection details from the BTP Destination Service
|
|
7
|
+
* 3. Configures an HTTP proxy through the Cloud Connector (Connectivity Service)
|
|
8
|
+
*
|
|
9
|
+
* The flow mirrors the Go implementation in pkg/adt/btp.go:
|
|
10
|
+
* - Parse VCAP_SERVICES → get destination/connectivity/xsuaa credentials
|
|
11
|
+
* - Call Destination Service API → get SAP URL, user, password
|
|
12
|
+
* - Create axios proxy config → route through Cloud Connector
|
|
13
|
+
* - Inject Proxy-Authorization header → connectivity service JWT token
|
|
14
|
+
*
|
|
15
|
+
* Token caching: Both destination and connectivity tokens are cached
|
|
16
|
+
* and refreshed 60 seconds before expiry to avoid request failures.
|
|
17
|
+
*/
|
|
18
|
+
import { logger } from '../server/logger.js';
|
|
19
|
+
/**
|
|
20
|
+
* Parse VCAP_SERVICES environment variable to extract BTP service credentials.
|
|
21
|
+
* Returns null if not running on BTP (VCAP_SERVICES not set).
|
|
22
|
+
*/
|
|
23
|
+
export function parseVCAPServices() {
|
|
24
|
+
const vcapJson = process.env.VCAP_SERVICES;
|
|
25
|
+
if (!vcapJson)
|
|
26
|
+
return null;
|
|
27
|
+
const vcap = JSON.parse(vcapJson);
|
|
28
|
+
const config = {
|
|
29
|
+
xsuaaUrl: '',
|
|
30
|
+
xsuaaClientId: '',
|
|
31
|
+
xsuaaSecret: '',
|
|
32
|
+
destinationUrl: '',
|
|
33
|
+
destinationClientId: '',
|
|
34
|
+
destinationSecret: '',
|
|
35
|
+
destinationTokenUrl: '',
|
|
36
|
+
connectivityProxyHost: '',
|
|
37
|
+
connectivityProxyPort: '',
|
|
38
|
+
connectivityClientId: '',
|
|
39
|
+
connectivitySecret: '',
|
|
40
|
+
connectivityTokenUrl: '',
|
|
41
|
+
};
|
|
42
|
+
// XSUAA binding
|
|
43
|
+
if (vcap.xsuaa?.[0]?.credentials) {
|
|
44
|
+
const c = vcap.xsuaa[0].credentials;
|
|
45
|
+
config.xsuaaUrl = c.url || '';
|
|
46
|
+
config.xsuaaClientId = c.clientid || '';
|
|
47
|
+
config.xsuaaSecret = c.clientsecret || '';
|
|
48
|
+
}
|
|
49
|
+
// Destination binding
|
|
50
|
+
if (vcap.destination?.[0]?.credentials) {
|
|
51
|
+
const c = vcap.destination[0].credentials;
|
|
52
|
+
config.destinationUrl = c.uri || c.url || '';
|
|
53
|
+
config.destinationClientId = c.clientid || '';
|
|
54
|
+
config.destinationSecret = c.clientsecret || '';
|
|
55
|
+
config.destinationTokenUrl = c.token_service_url || '';
|
|
56
|
+
// Fallback: construct from URL
|
|
57
|
+
if (!config.destinationTokenUrl && c.url) {
|
|
58
|
+
config.destinationTokenUrl = `${c.url.replace(/\/$/, '')}/oauth/token`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Connectivity binding
|
|
62
|
+
if (vcap.connectivity?.[0]?.credentials) {
|
|
63
|
+
const c = vcap.connectivity[0].credentials;
|
|
64
|
+
config.connectivityProxyHost = c.onpremise_proxy_host || '';
|
|
65
|
+
config.connectivityProxyPort = c.onpremise_proxy_http_port || '';
|
|
66
|
+
config.connectivityClientId = c.clientid || '';
|
|
67
|
+
config.connectivitySecret = c.clientsecret || '';
|
|
68
|
+
config.connectivityTokenUrl = c.token_service_url || '';
|
|
69
|
+
// Fallback + ensure /oauth/token suffix
|
|
70
|
+
if (!config.connectivityTokenUrl && c.url) {
|
|
71
|
+
config.connectivityTokenUrl = `${c.url.replace(/\/$/, '')}/oauth/token`;
|
|
72
|
+
}
|
|
73
|
+
else if (config.connectivityTokenUrl && !config.connectivityTokenUrl.endsWith('/oauth/token')) {
|
|
74
|
+
config.connectivityTokenUrl = `${config.connectivityTokenUrl.replace(/\/$/, '')}/oauth/token`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
logger.info('BTP VCAP_SERVICES parsed', {
|
|
78
|
+
hasXsuaa: !!config.xsuaaUrl,
|
|
79
|
+
hasDestination: !!config.destinationUrl,
|
|
80
|
+
hasConnectivity: !!config.connectivityProxyHost,
|
|
81
|
+
});
|
|
82
|
+
return config;
|
|
83
|
+
}
|
|
84
|
+
// ─── Destination Service ─────────────────────────────────────────────
|
|
85
|
+
/**
|
|
86
|
+
* Fetch an OAuth2 client_credentials token.
|
|
87
|
+
* Used for both Destination Service and Connectivity Service tokens.
|
|
88
|
+
*/
|
|
89
|
+
async function fetchClientCredentialsToken(tokenUrl, clientId, clientSecret) {
|
|
90
|
+
const body = new URLSearchParams({
|
|
91
|
+
grant_type: 'client_credentials',
|
|
92
|
+
client_id: clientId,
|
|
93
|
+
client_secret: clientSecret,
|
|
94
|
+
});
|
|
95
|
+
const resp = await fetch(tokenUrl, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
98
|
+
body: body.toString(),
|
|
99
|
+
});
|
|
100
|
+
if (!resp.ok) {
|
|
101
|
+
const text = await resp.text();
|
|
102
|
+
throw new Error(`Token endpoint returned HTTP ${resp.status}: ${text.slice(0, 200)}`);
|
|
103
|
+
}
|
|
104
|
+
const data = (await resp.json());
|
|
105
|
+
return { accessToken: data.access_token, expiresIn: data.expires_in };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Look up a destination from the BTP Destination Service.
|
|
109
|
+
* Returns SAP URL, credentials, and proxy type.
|
|
110
|
+
*/
|
|
111
|
+
export async function lookupDestination(btpConfig, destinationName) {
|
|
112
|
+
// Get token for Destination Service API
|
|
113
|
+
const tokenUrl = btpConfig.destinationTokenUrl || `${btpConfig.xsuaaUrl}/oauth/token`;
|
|
114
|
+
const { accessToken } = await fetchClientCredentialsToken(tokenUrl, btpConfig.destinationClientId, btpConfig.destinationSecret);
|
|
115
|
+
// Call Destination Service
|
|
116
|
+
const destUrl = `${btpConfig.destinationUrl.replace(/\/$/, '')}/destination-configuration/v1/destinations/${encodeURIComponent(destinationName)}`;
|
|
117
|
+
const resp = await fetch(destUrl, {
|
|
118
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
119
|
+
});
|
|
120
|
+
if (!resp.ok) {
|
|
121
|
+
const text = await resp.text();
|
|
122
|
+
throw new Error(`Destination Service returned HTTP ${resp.status}: ${text.slice(0, 200)}`);
|
|
123
|
+
}
|
|
124
|
+
const data = (await resp.json());
|
|
125
|
+
logger.info('BTP destination resolved', {
|
|
126
|
+
name: data.destinationConfiguration.Name,
|
|
127
|
+
url: data.destinationConfiguration.URL,
|
|
128
|
+
auth: data.destinationConfiguration.Authentication,
|
|
129
|
+
proxyType: data.destinationConfiguration.ProxyType,
|
|
130
|
+
});
|
|
131
|
+
return data.destinationConfiguration;
|
|
132
|
+
}
|
|
133
|
+
// ─── Connectivity Proxy ──────────────────────────────────────────────
|
|
134
|
+
/**
|
|
135
|
+
* Create a proxy configuration for routing through the Cloud Connector.
|
|
136
|
+
*
|
|
137
|
+
* Returns a BTPProxyConfig with a token getter that caches the connectivity
|
|
138
|
+
* JWT and auto-refreshes it 60 seconds before expiry.
|
|
139
|
+
*/
|
|
140
|
+
export function createConnectivityProxy(btpConfig) {
|
|
141
|
+
if (!btpConfig.connectivityProxyHost)
|
|
142
|
+
return null;
|
|
143
|
+
let cachedToken = '';
|
|
144
|
+
let expiresAt = 0;
|
|
145
|
+
return {
|
|
146
|
+
host: btpConfig.connectivityProxyHost,
|
|
147
|
+
port: Number.parseInt(btpConfig.connectivityProxyPort || '20003', 10),
|
|
148
|
+
protocol: 'http',
|
|
149
|
+
getProxyToken: async () => {
|
|
150
|
+
// Return cached token if still valid (60s buffer)
|
|
151
|
+
if (cachedToken && Date.now() < expiresAt) {
|
|
152
|
+
return cachedToken;
|
|
153
|
+
}
|
|
154
|
+
const { accessToken, expiresIn } = await fetchClientCredentialsToken(btpConfig.connectivityTokenUrl, btpConfig.connectivityClientId, btpConfig.connectivitySecret);
|
|
155
|
+
cachedToken = accessToken;
|
|
156
|
+
expiresAt = Date.now() + (expiresIn - 60) * 1000;
|
|
157
|
+
return cachedToken;
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Look up a destination with the user's JWT token for principal propagation.
|
|
163
|
+
*
|
|
164
|
+
* This is the key API for per-user SAP authentication:
|
|
165
|
+
* 1. Caller passes the user's JWT (from XSUAA/OIDC)
|
|
166
|
+
* 2. Destination Service validates the JWT and generates auth tokens
|
|
167
|
+
* 3. For PrincipalPropagation destinations: returns SAP-Connectivity-Authentication header
|
|
168
|
+
* 4. For OAuth2SAMLBearerAssertion destinations: returns a Bearer token
|
|
169
|
+
*
|
|
170
|
+
* The returned tokens are per-user and typically valid for 5-10 minutes.
|
|
171
|
+
*
|
|
172
|
+
* Reference: SAP Destination Service REST API "Find Destination" endpoint
|
|
173
|
+
* https://api.sap.com/api/SAP_CP_CF_Connectivity_Destination/resource/Find_a_Destination
|
|
174
|
+
*/
|
|
175
|
+
export async function lookupDestinationWithUserToken(btpConfig, destinationName, userJwt) {
|
|
176
|
+
// Get a service token for Destination Service API
|
|
177
|
+
const tokenUrl = btpConfig.destinationTokenUrl || `${btpConfig.xsuaaUrl}/oauth/token`;
|
|
178
|
+
const { accessToken: serviceToken } = await fetchClientCredentialsToken(tokenUrl, btpConfig.destinationClientId, btpConfig.destinationSecret);
|
|
179
|
+
// Log JWT claims for PP debugging (decode payload without verification)
|
|
180
|
+
try {
|
|
181
|
+
const parts = userJwt.split('.');
|
|
182
|
+
if (parts.length === 3) {
|
|
183
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString());
|
|
184
|
+
logger.debug('PP user JWT claims', {
|
|
185
|
+
destination: destinationName,
|
|
186
|
+
grantType: payload.grant_type,
|
|
187
|
+
sub: payload.sub,
|
|
188
|
+
email: payload.email,
|
|
189
|
+
userUuid: payload.user_uuid,
|
|
190
|
+
zid: payload.zid,
|
|
191
|
+
iss: payload.iss,
|
|
192
|
+
aud: Array.isArray(payload.aud) ? payload.aud.join(',') : payload.aud,
|
|
193
|
+
azp: payload.azp,
|
|
194
|
+
scope: payload.scope?.join?.(' ') ?? payload.scope,
|
|
195
|
+
origin: payload.origin,
|
|
196
|
+
exp: payload.exp,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
logger.debug('PP user JWT: failed to decode claims');
|
|
202
|
+
}
|
|
203
|
+
// Call Find Destination API with X-User-Token header
|
|
204
|
+
// This triggers the Destination Service to perform the user-specific
|
|
205
|
+
// authentication flow (e.g., generate SAML assertion for PrincipalPropagation)
|
|
206
|
+
const destUrl = `${btpConfig.destinationUrl.replace(/\/$/, '')}/destination-configuration/v1/destinations/${encodeURIComponent(destinationName)}`;
|
|
207
|
+
const resp = await fetch(destUrl, {
|
|
208
|
+
headers: {
|
|
209
|
+
Authorization: `Bearer ${serviceToken}`,
|
|
210
|
+
'X-user-token': userJwt,
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
if (!resp.ok) {
|
|
214
|
+
const text = await resp.text();
|
|
215
|
+
throw new Error(`Destination Service (per-user) returned HTTP ${resp.status} for '${destinationName}': ${text.slice(0, 300)}`);
|
|
216
|
+
}
|
|
217
|
+
const data = (await resp.json());
|
|
218
|
+
const dest = data.destinationConfiguration;
|
|
219
|
+
const tokens = {};
|
|
220
|
+
// Log raw auth response for PP debugging.
|
|
221
|
+
// Field names avoid "token" substring to prevent logger redaction.
|
|
222
|
+
const rawEntries = data.authTokens?.map((t) => ({
|
|
223
|
+
entryType: t.type,
|
|
224
|
+
httpHeaderKey: t.http_header?.key,
|
|
225
|
+
hasValue: !!t.value,
|
|
226
|
+
hasHttpHeaderValue: !!t.http_header?.value,
|
|
227
|
+
entryError: t.error,
|
|
228
|
+
}));
|
|
229
|
+
logger.debug('Destination Service PP response', {
|
|
230
|
+
destination: destinationName,
|
|
231
|
+
authentication: dest.Authentication,
|
|
232
|
+
proxyType: dest.ProxyType,
|
|
233
|
+
url: dest.URL,
|
|
234
|
+
ppEntryCount: data.authTokens?.length ?? 0,
|
|
235
|
+
ppEntries: rawEntries ?? 'NONE',
|
|
236
|
+
});
|
|
237
|
+
// Extract auth tokens from the response
|
|
238
|
+
if (data.authTokens) {
|
|
239
|
+
for (const token of data.authTokens) {
|
|
240
|
+
if (token.error) {
|
|
241
|
+
logger.error('Destination Service auth token error', {
|
|
242
|
+
destination: destinationName,
|
|
243
|
+
tokenType: token.type,
|
|
244
|
+
error: token.error,
|
|
245
|
+
});
|
|
246
|
+
throw new Error(`Destination Service auth token error for '${destinationName}': ${token.error}`);
|
|
247
|
+
}
|
|
248
|
+
// SAP-Connectivity-Authentication header (used by Cloud Connector for PP)
|
|
249
|
+
if (token.http_header?.key === 'SAP-Connectivity-Authentication') {
|
|
250
|
+
tokens.sapConnectivityAuth = token.http_header.value;
|
|
251
|
+
logger.debug('PP: SAP-Connectivity-Authentication header extracted', {
|
|
252
|
+
destination: destinationName,
|
|
253
|
+
headerValueLength: token.http_header.value.length,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
// Bearer token (used for OAuth2SAMLBearerAssertion destinations)
|
|
257
|
+
if (token.type === 'Bearer') {
|
|
258
|
+
tokens.bearerToken = token.value;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
logger.warn('Destination Service returned no authTokens — trying jwt-bearer exchange fallback', {
|
|
264
|
+
destination: destinationName,
|
|
265
|
+
authentication: dest.Authentication,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
// ─── PP jwt-bearer fallback (Option 2) ─────────────────────────────
|
|
269
|
+
//
|
|
270
|
+
// Background: The BTP Destination Service SHOULD return authTokens containing
|
|
271
|
+
// the SAP-Connectivity-Authentication header for PrincipalPropagation destinations.
|
|
272
|
+
// In practice, it often returns NO authTokens (empty response). This is a known
|
|
273
|
+
// issue — the Destination Service simply omits the field.
|
|
274
|
+
//
|
|
275
|
+
// Workaround: We perform a jwt-bearer token exchange with the Connectivity
|
|
276
|
+
// Service's XSUAA to verify the user JWT is valid. If the exchange succeeds,
|
|
277
|
+
// we send the ORIGINAL user JWT as SAP-Connectivity-Authentication (Option 2
|
|
278
|
+
// per SAP docs page 211). The Cloud Connector extracts the user identity from
|
|
279
|
+
// this header and generates the X.509 certificate.
|
|
280
|
+
//
|
|
281
|
+
// Why Option 2 and not Option 1?
|
|
282
|
+
// - Option 1 sends the EXCHANGED token as Proxy-Authorization
|
|
283
|
+
// - The CC couldn't extract the principal from the exchanged token
|
|
284
|
+
// (CC trace: "no principal available, injecting empty certificate")
|
|
285
|
+
// - Option 2 sends the ORIGINAL user JWT as SAP-Connectivity-Authentication
|
|
286
|
+
// + regular connectivity proxy token as Proxy-Authorization
|
|
287
|
+
// - The CC successfully extracts the user email from the original JWT
|
|
288
|
+
//
|
|
289
|
+
// Reference: SAP BTP Connectivity docs page 209-213
|
|
290
|
+
// https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/configure-principal-propagation-via-user-exchange-token
|
|
291
|
+
if (!tokens.sapConnectivityAuth && dest.Authentication === 'PrincipalPropagation' && btpConfig.connectivityClientId) {
|
|
292
|
+
logger.info('PP jwt-bearer exchange: attempting direct exchange with Connectivity Service', {
|
|
293
|
+
destination: destinationName,
|
|
294
|
+
connectivityUrl: btpConfig.connectivityTokenUrl,
|
|
295
|
+
});
|
|
296
|
+
try {
|
|
297
|
+
// Exchange user JWT via jwt-bearer grant type with Connectivity Service credentials.
|
|
298
|
+
// This validates the user JWT and proves we have a legitimate user token.
|
|
299
|
+
// The exchange itself isn't used for auth — we use the original JWT instead.
|
|
300
|
+
const exchangeResp = await fetch(btpConfig.connectivityTokenUrl, {
|
|
301
|
+
method: 'POST',
|
|
302
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
303
|
+
body: new URLSearchParams({
|
|
304
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
305
|
+
client_id: btpConfig.connectivityClientId,
|
|
306
|
+
client_secret: btpConfig.connectivitySecret,
|
|
307
|
+
assertion: userJwt,
|
|
308
|
+
token_format: 'jwt',
|
|
309
|
+
response_type: 'token',
|
|
310
|
+
}).toString(),
|
|
311
|
+
});
|
|
312
|
+
if (exchangeResp.ok) {
|
|
313
|
+
await exchangeResp.json(); // consume response body
|
|
314
|
+
// Option 2: Send the ORIGINAL user JWT as SAP-Connectivity-Authentication.
|
|
315
|
+
// The CC reads this header, extracts the user identity (email), and generates
|
|
316
|
+
// a short-lived X.509 certificate with CN=${email}. The regular connectivity
|
|
317
|
+
// proxy token (from btpProxy.getProxyToken()) is sent as Proxy-Authorization.
|
|
318
|
+
tokens.sapConnectivityAuth = `Bearer ${userJwt}`;
|
|
319
|
+
logger.info('PP: using Option 2 (SAP-Connectivity-Authentication with original JWT)', {
|
|
320
|
+
destination: destinationName,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
const errText = await exchangeResp.text();
|
|
325
|
+
logger.error('PP jwt-bearer exchange: failed', {
|
|
326
|
+
destination: destinationName,
|
|
327
|
+
status: exchangeResp.status,
|
|
328
|
+
error: errText.slice(0, 300),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
logger.error('PP jwt-bearer exchange: error', {
|
|
334
|
+
destination: destinationName,
|
|
335
|
+
error: err instanceof Error ? err.message : String(err),
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
logger.info('BTP destination resolved (per-user)', {
|
|
340
|
+
name: dest.Name,
|
|
341
|
+
url: dest.URL,
|
|
342
|
+
auth: dest.Authentication,
|
|
343
|
+
hasConnectivityAuth: !!tokens.sapConnectivityAuth,
|
|
344
|
+
hasBearer: !!tokens.bearerToken,
|
|
345
|
+
});
|
|
346
|
+
return { destination: dest, authTokens: tokens };
|
|
347
|
+
}
|
|
348
|
+
// ─── Top-Level Resolver ──────────────────────────────────────────────
|
|
349
|
+
/**
|
|
350
|
+
* Resolve BTP destination and connectivity proxy.
|
|
351
|
+
* Called on startup when SAP_BTP_DESTINATION env var is set.
|
|
352
|
+
*
|
|
353
|
+
* Returns the resolved SAP connection config to override defaults.
|
|
354
|
+
*/
|
|
355
|
+
export async function resolveBTPDestination(destinationName) {
|
|
356
|
+
const btpConfig = parseVCAPServices();
|
|
357
|
+
if (!btpConfig) {
|
|
358
|
+
throw new Error('SAP_BTP_DESTINATION is set but VCAP_SERVICES is not available. Are you running on BTP CF?');
|
|
359
|
+
}
|
|
360
|
+
const dest = await lookupDestination(btpConfig, destinationName);
|
|
361
|
+
const proxy = dest.ProxyType === 'OnPremise' ? createConnectivityProxy(btpConfig) : null;
|
|
362
|
+
return {
|
|
363
|
+
url: dest.URL,
|
|
364
|
+
username: dest.User,
|
|
365
|
+
password: dest.Password,
|
|
366
|
+
client: dest['sap-client'] || '001',
|
|
367
|
+
proxy,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Get the app's public URL from VCAP_APPLICATION.
|
|
372
|
+
*
|
|
373
|
+
* CF sets VCAP_APPLICATION with application_uris containing the app's
|
|
374
|
+
* public route. Returns the first URI as an https URL.
|
|
375
|
+
*/
|
|
376
|
+
export function getAppUrl() {
|
|
377
|
+
const vcapApp = process.env.VCAP_APPLICATION;
|
|
378
|
+
if (!vcapApp)
|
|
379
|
+
return undefined;
|
|
380
|
+
try {
|
|
381
|
+
const app = JSON.parse(vcapApp);
|
|
382
|
+
const uris = app.application_uris ?? app.uris;
|
|
383
|
+
if (Array.isArray(uris) && uris.length > 0) {
|
|
384
|
+
return `https://${uris[0]}`;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
// Not valid JSON
|
|
389
|
+
}
|
|
390
|
+
return undefined;
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=btp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"btp.js","sourceRoot":"","sources":["../../ts-src/adt/btp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADT Client — main facade for all SAP ADT operations.
|
|
3
|
+
*
|
|
4
|
+
* This is the entry point for all SAP interactions. It wires together:
|
|
5
|
+
* - AdtHttpClient (HTTP transport, CSRF, cookies)
|
|
6
|
+
* - SafetyConfig (operation/package/transport gating)
|
|
7
|
+
* - FeatureConfig (optional feature detection)
|
|
8
|
+
*
|
|
9
|
+
* Every public method checks safety before making any HTTP call.
|
|
10
|
+
* The client is stateless between calls (no cached object state),
|
|
11
|
+
* except for CSRF token and session cookies managed by AdtHttpClient.
|
|
12
|
+
*
|
|
13
|
+
* Architecture: The client exposes high-level operations grouped by domain.
|
|
14
|
+
* Read operations are directly on the client, while CRUD, DevTools, etc.
|
|
15
|
+
* are imported from their respective modules when needed by handlers.
|
|
16
|
+
* This keeps the client class manageable (not a 2,400-line God class).
|
|
17
|
+
*/
|
|
18
|
+
import type { AdtClientConfig } from './config.js';
|
|
19
|
+
import { AdtHttpClient } from './http.js';
|
|
20
|
+
import { type SafetyConfig } from './safety.js';
|
|
21
|
+
import type { AdtSearchResult } from './types.js';
|
|
22
|
+
export declare class AdtClient {
|
|
23
|
+
readonly http: AdtHttpClient;
|
|
24
|
+
readonly safety: SafetyConfig;
|
|
25
|
+
/** The configured SAP username (from --user / SAP_USER) */
|
|
26
|
+
readonly username: string;
|
|
27
|
+
constructor(options?: Partial<AdtClientConfig>);
|
|
28
|
+
/** Get program source code */
|
|
29
|
+
getProgram(name: string): Promise<string>;
|
|
30
|
+
/** Get class source code (main include by default) */
|
|
31
|
+
getClass(name: string, include?: string): Promise<string>;
|
|
32
|
+
/** Get interface source code */
|
|
33
|
+
getInterface(name: string): Promise<string>;
|
|
34
|
+
/** Get function module source code */
|
|
35
|
+
getFunction(group: string, name: string): Promise<string>;
|
|
36
|
+
/** Get function group structure (list of function modules) */
|
|
37
|
+
getFunctionGroup(name: string): Promise<{
|
|
38
|
+
name: string;
|
|
39
|
+
functions: string[];
|
|
40
|
+
}>;
|
|
41
|
+
/** Get function group source code */
|
|
42
|
+
getFunctionGroupSource(name: string): Promise<string>;
|
|
43
|
+
/** Get include source code */
|
|
44
|
+
getInclude(name: string): Promise<string>;
|
|
45
|
+
/** Get CDS view source code (DDLS) */
|
|
46
|
+
getDdls(name: string): Promise<string>;
|
|
47
|
+
/** Get behavior definition source code (BDEF) */
|
|
48
|
+
getBdef(name: string): Promise<string>;
|
|
49
|
+
/** Get service definition source code (SRVD) */
|
|
50
|
+
getSrvd(name: string): Promise<string>;
|
|
51
|
+
/** Get table definition source code */
|
|
52
|
+
getTable(name: string): Promise<string>;
|
|
53
|
+
/** Get view definition source code */
|
|
54
|
+
getView(name: string): Promise<string>;
|
|
55
|
+
/** Search for ABAP objects by name pattern */
|
|
56
|
+
searchObject(query: string, maxResults?: number): Promise<AdtSearchResult[]>;
|
|
57
|
+
/** Get package contents (objects and subpackages) */
|
|
58
|
+
getPackageContents(packageName: string): Promise<Array<{
|
|
59
|
+
type: string;
|
|
60
|
+
name: string;
|
|
61
|
+
description: string;
|
|
62
|
+
uri: string;
|
|
63
|
+
}>>;
|
|
64
|
+
/** Get table contents via data preview */
|
|
65
|
+
getTableContents(tableName: string, maxRows?: number, sqlFilter?: string): Promise<{
|
|
66
|
+
columns: string[];
|
|
67
|
+
rows: Record<string, string>[];
|
|
68
|
+
}>;
|
|
69
|
+
/** Execute freestyle SQL query */
|
|
70
|
+
runQuery(sql: string, maxRows?: number): Promise<{
|
|
71
|
+
columns: string[];
|
|
72
|
+
rows: Record<string, string>[];
|
|
73
|
+
}>;
|
|
74
|
+
/** Get system info as structured JSON (user, system details from discovery XML) */
|
|
75
|
+
getSystemInfo(): Promise<string>;
|
|
76
|
+
/** Get installed SAP components */
|
|
77
|
+
getInstalledComponents(): Promise<Array<{
|
|
78
|
+
name: string;
|
|
79
|
+
release: string;
|
|
80
|
+
description: string;
|
|
81
|
+
}>>;
|
|
82
|
+
/** Get message class messages */
|
|
83
|
+
getMessages(messageClass: string): Promise<string>;
|
|
84
|
+
/** Get program text elements */
|
|
85
|
+
getTextElements(program: string): Promise<string>;
|
|
86
|
+
/** Get program variants */
|
|
87
|
+
getVariants(program: string): Promise<string>;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../ts-src/adt/client.ts"],"names":[],"mappings":"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"}
|