arc-1 0.9.18 → 0.9.19

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.
Files changed (92) hide show
  1. package/README.md +26 -26
  2. package/dist/adt/config.d.ts +1 -1
  3. package/dist/adt/config.d.ts.map +1 -1
  4. package/dist/adt/http.d.ts +1 -1
  5. package/dist/adt/http.d.ts.map +1 -1
  6. package/dist/adt/http.js.map +1 -1
  7. package/dist/authz/policy.d.ts +6 -0
  8. package/dist/authz/policy.d.ts.map +1 -1
  9. package/dist/authz/policy.js +20 -0
  10. package/dist/authz/policy.js.map +1 -1
  11. package/dist/cli.js +21 -3
  12. package/dist/cli.js.map +1 -1
  13. package/dist/handlers/dispatch.d.ts +3 -0
  14. package/dist/handlers/dispatch.d.ts.map +1 -1
  15. package/dist/handlers/dispatch.js +71 -53
  16. package/dist/handlers/dispatch.js.map +1 -1
  17. package/dist/handlers/schemas.d.ts +4 -4
  18. package/dist/plugins/manifest-interpreter.d.ts +25 -0
  19. package/dist/plugins/manifest-interpreter.d.ts.map +1 -0
  20. package/dist/plugins/manifest-interpreter.js +124 -0
  21. package/dist/plugins/manifest-interpreter.js.map +1 -0
  22. package/dist/public/define-tool.d.ts +9 -0
  23. package/dist/public/define-tool.d.ts.map +1 -0
  24. package/dist/public/define-tool.js +25 -0
  25. package/dist/public/define-tool.js.map +1 -0
  26. package/dist/public/index.d.ts +9 -0
  27. package/dist/public/index.d.ts.map +1 -0
  28. package/dist/public/index.js +10 -0
  29. package/dist/public/index.js.map +1 -0
  30. package/dist/public/testing.d.ts +26 -0
  31. package/dist/public/testing.d.ts.map +1 -0
  32. package/dist/public/testing.js +39 -0
  33. package/dist/public/testing.js.map +1 -0
  34. package/dist/public/types.d.ts +87 -0
  35. package/dist/public/types.d.ts.map +1 -0
  36. package/dist/public/types.js +4 -0
  37. package/dist/public/types.js.map +1 -0
  38. package/dist/registry/tool-registry.d.ts +74 -0
  39. package/dist/registry/tool-registry.d.ts.map +1 -0
  40. package/dist/registry/tool-registry.js +59 -0
  41. package/dist/registry/tool-registry.js.map +1 -0
  42. package/dist/server/app-url.d.ts +31 -0
  43. package/dist/server/app-url.d.ts.map +1 -0
  44. package/dist/server/app-url.js +50 -0
  45. package/dist/server/app-url.js.map +1 -0
  46. package/dist/server/audit.d.ts +4 -0
  47. package/dist/server/audit.d.ts.map +1 -1
  48. package/dist/server/audit.js.map +1 -1
  49. package/dist/server/config.d.ts.map +1 -1
  50. package/dist/server/config.js +19 -0
  51. package/dist/server/config.js.map +1 -1
  52. package/dist/server/http.d.ts +15 -46
  53. package/dist/server/http.d.ts.map +1 -1
  54. package/dist/server/http.js +105 -375
  55. package/dist/server/http.js.map +1 -1
  56. package/dist/server/logger.d.ts +22 -0
  57. package/dist/server/logger.d.ts.map +1 -1
  58. package/dist/server/logger.js +22 -0
  59. package/dist/server/logger.js.map +1 -1
  60. package/dist/server/plugin-loader.d.ts +19 -0
  61. package/dist/server/plugin-loader.d.ts.map +1 -0
  62. package/dist/server/plugin-loader.js +162 -0
  63. package/dist/server/plugin-loader.js.map +1 -0
  64. package/dist/server/safe-http-client.d.ts +38 -0
  65. package/dist/server/safe-http-client.d.ts.map +1 -0
  66. package/dist/server/safe-http-client.js +129 -0
  67. package/dist/server/safe-http-client.js.map +1 -0
  68. package/dist/server/server.d.ts +2 -2
  69. package/dist/server/server.d.ts.map +1 -1
  70. package/dist/server/server.js +36 -7
  71. package/dist/server/server.js.map +1 -1
  72. package/dist/server/types.d.ts +8 -0
  73. package/dist/server/types.d.ts.map +1 -1
  74. package/dist/server/types.js +2 -0
  75. package/dist/server/types.js.map +1 -1
  76. package/package.json +24 -8
  77. package/dist/adt/btp.d.ts +0 -140
  78. package/dist/adt/btp.d.ts.map +0 -1
  79. package/dist/adt/btp.js +0 -427
  80. package/dist/adt/btp.js.map +0 -1
  81. package/dist/server/oauth-state.d.ts +0 -92
  82. package/dist/server/oauth-state.d.ts.map +0 -1
  83. package/dist/server/oauth-state.js +0 -163
  84. package/dist/server/oauth-state.js.map +0 -1
  85. package/dist/server/stateless-client-store.d.ts +0 -173
  86. package/dist/server/stateless-client-store.d.ts.map +0 -1
  87. package/dist/server/stateless-client-store.js +0 -503
  88. package/dist/server/stateless-client-store.js.map +0 -1
  89. package/dist/server/xsuaa.d.ts +0 -188
  90. package/dist/server/xsuaa.d.ts.map +0 -1
  91. package/dist/server/xsuaa.js +0 -464
  92. package/dist/server/xsuaa.js.map +0 -1
package/dist/adt/btp.js DELETED
@@ -1,427 +0,0 @@
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
- * Startup path (lookupDestination, resolveBTPDestination) uses direct fetch
10
- * to the Destination Service API. Per-user principal propagation path
11
- * (lookupDestinationWithUserToken) uses SAP Cloud SDK's getDestination()
12
- * for automatic token management and per-user caching.
13
- *
14
- * Token caching: Connectivity proxy tokens are cached and refreshed 60 seconds
15
- * before expiry. Per-user destination tokens are cached by the SDK.
16
- */
17
- import { getDestination, } from '@sap-cloud-sdk/connectivity';
18
- import { logger } from '../server/logger.js';
19
- import { destinationPpHint } from './errors.js';
20
- /**
21
- * Parse VCAP_SERVICES environment variable to extract BTP service credentials.
22
- * Returns null if not running on BTP (VCAP_SERVICES not set).
23
- */
24
- export function parseVCAPServices() {
25
- const vcapJson = process.env.VCAP_SERVICES;
26
- if (!vcapJson)
27
- return null;
28
- const vcap = JSON.parse(vcapJson);
29
- const config = {
30
- xsuaaUrl: '',
31
- xsuaaClientId: '',
32
- xsuaaSecret: '',
33
- destinationUrl: '',
34
- destinationClientId: '',
35
- destinationSecret: '',
36
- destinationTokenUrl: '',
37
- connectivityProxyHost: '',
38
- connectivityProxyPort: '',
39
- connectivityClientId: '',
40
- connectivitySecret: '',
41
- connectivityTokenUrl: '',
42
- };
43
- // XSUAA binding
44
- if (vcap.xsuaa?.[0]?.credentials) {
45
- const c = vcap.xsuaa[0].credentials;
46
- config.xsuaaUrl = c.url || '';
47
- config.xsuaaClientId = c.clientid || '';
48
- config.xsuaaSecret = c.clientsecret || '';
49
- }
50
- // Destination binding
51
- if (vcap.destination?.[0]?.credentials) {
52
- const c = vcap.destination[0].credentials;
53
- config.destinationUrl = c.uri || c.url || '';
54
- config.destinationClientId = c.clientid || '';
55
- config.destinationSecret = c.clientsecret || '';
56
- config.destinationTokenUrl = c.token_service_url || '';
57
- // Fallback: construct from URL
58
- if (!config.destinationTokenUrl && c.url) {
59
- config.destinationTokenUrl = `${c.url.replace(/\/$/, '')}/oauth/token`;
60
- }
61
- }
62
- // Connectivity binding
63
- if (vcap.connectivity?.[0]?.credentials) {
64
- const c = vcap.connectivity[0].credentials;
65
- config.connectivityProxyHost = c.onpremise_proxy_host || '';
66
- config.connectivityProxyPort = c.onpremise_proxy_http_port || '';
67
- config.connectivityClientId = c.clientid || '';
68
- config.connectivitySecret = c.clientsecret || '';
69
- config.connectivityTokenUrl = c.token_service_url || '';
70
- // Fallback + ensure /oauth/token suffix
71
- if (!config.connectivityTokenUrl && c.url) {
72
- config.connectivityTokenUrl = `${c.url.replace(/\/$/, '')}/oauth/token`;
73
- }
74
- else if (config.connectivityTokenUrl && !config.connectivityTokenUrl.endsWith('/oauth/token')) {
75
- config.connectivityTokenUrl = `${config.connectivityTokenUrl.replace(/\/$/, '')}/oauth/token`;
76
- }
77
- }
78
- logger.info('BTP VCAP_SERVICES parsed', {
79
- hasXsuaa: !!config.xsuaaUrl,
80
- hasDestination: !!config.destinationUrl,
81
- hasConnectivity: !!config.connectivityProxyHost,
82
- });
83
- return config;
84
- }
85
- // ─── Destination Service ─────────────────────────────────────────────
86
- /**
87
- * Fetch an OAuth2 client_credentials token.
88
- * Used for both Destination Service and Connectivity Service tokens.
89
- */
90
- async function fetchClientCredentialsToken(tokenUrl, clientId, clientSecret) {
91
- const body = new URLSearchParams({
92
- grant_type: 'client_credentials',
93
- client_id: clientId,
94
- client_secret: clientSecret,
95
- });
96
- const resp = await fetch(tokenUrl, {
97
- method: 'POST',
98
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
99
- body: body.toString(),
100
- });
101
- if (!resp.ok) {
102
- const text = await resp.text();
103
- throw new Error(`Token endpoint returned HTTP ${resp.status}: ${text.slice(0, 200)}`);
104
- }
105
- const data = (await resp.json());
106
- return { accessToken: data.access_token, expiresIn: data.expires_in };
107
- }
108
- /**
109
- * Look up a destination from the BTP Destination Service.
110
- * Returns SAP URL, credentials, and proxy type.
111
- */
112
- export async function lookupDestination(btpConfig, destinationName) {
113
- // Get token for Destination Service API
114
- const tokenUrl = btpConfig.destinationTokenUrl || `${btpConfig.xsuaaUrl}/oauth/token`;
115
- const { accessToken } = await fetchClientCredentialsToken(tokenUrl, btpConfig.destinationClientId, btpConfig.destinationSecret);
116
- // Call Destination Service
117
- const destUrl = `${btpConfig.destinationUrl.replace(/\/$/, '')}/destination-configuration/v1/destinations/${encodeURIComponent(destinationName)}`;
118
- const resp = await fetch(destUrl, {
119
- headers: { Authorization: `Bearer ${accessToken}` },
120
- });
121
- if (!resp.ok) {
122
- const text = await resp.text();
123
- throw new Error(`Destination Service returned HTTP ${resp.status}: ${text.slice(0, 200)}`);
124
- }
125
- const data = (await resp.json());
126
- logger.info('BTP destination resolved', {
127
- name: data.destinationConfiguration.Name,
128
- url: data.destinationConfiguration.URL,
129
- auth: data.destinationConfiguration.Authentication,
130
- proxyType: data.destinationConfiguration.ProxyType,
131
- locationId: data.destinationConfiguration.CloudConnectorLocationId,
132
- });
133
- return data.destinationConfiguration;
134
- }
135
- // ─── Connectivity Proxy ──────────────────────────────────────────────
136
- /**
137
- * Create a proxy configuration for routing through the Cloud Connector.
138
- *
139
- * Returns a BTPProxyConfig with a token getter that caches the connectivity
140
- * JWT and auto-refreshes it 60 seconds before expiry.
141
- */
142
- export function createConnectivityProxy(btpConfig, locationId) {
143
- if (!btpConfig.connectivityProxyHost)
144
- return null;
145
- let cachedToken = '';
146
- let expiresAt = 0;
147
- return {
148
- host: btpConfig.connectivityProxyHost,
149
- port: Number.parseInt(btpConfig.connectivityProxyPort || '20003', 10),
150
- protocol: 'http',
151
- locationId,
152
- getProxyToken: async () => {
153
- // Return cached token if still valid (60s buffer)
154
- if (cachedToken && Date.now() < expiresAt) {
155
- return cachedToken;
156
- }
157
- const { accessToken, expiresIn } = await fetchClientCredentialsToken(btpConfig.connectivityTokenUrl, btpConfig.connectivityClientId, btpConfig.connectivitySecret);
158
- cachedToken = accessToken;
159
- expiresAt = Date.now() + (expiresIn - 60) * 1000;
160
- return cachedToken;
161
- },
162
- };
163
- }
164
- /**
165
- * Look up a destination with the user's JWT token for principal propagation.
166
- *
167
- * Uses SAP Cloud SDK's `getDestination()` to resolve the destination with per-user
168
- * JWT. The SDK handles service token acquisition, X-User-Token header injection,
169
- * and per-user destination caching.
170
- *
171
- * This is the key API for per-user SAP authentication:
172
- * 1. Caller passes the user's JWT (from XSUAA/OIDC)
173
- * 2. SDK calls the Destination Service with X-User-Token header
174
- * 3. For PrincipalPropagation destinations: returns SAP-Connectivity-Authentication header
175
- * 4. For OAuth2SAMLBearerAssertion destinations: returns a Bearer token
176
- *
177
- * Includes a jwt-bearer fallback (Option 2) when the Destination Service returns
178
- * no auth tokens — uses direct fetch to the Connectivity Service token URL.
179
- *
180
- * @param btpConfig - BTP service credentials (needed for jwt-bearer fallback only)
181
- */
182
- export async function lookupDestinationWithUserToken(btpConfig, destinationName, userJwt) {
183
- // Log JWT claims for PP debugging (decode payload without verification)
184
- try {
185
- const parts = userJwt.split('.');
186
- if (parts.length === 3) {
187
- const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString());
188
- logger.debug('PP user JWT claims', {
189
- destination: destinationName,
190
- grantType: payload.grant_type,
191
- sub: payload.sub,
192
- email: payload.email,
193
- userUuid: payload.user_uuid,
194
- zid: payload.zid,
195
- iss: payload.iss,
196
- aud: Array.isArray(payload.aud) ? payload.aud.join(',') : payload.aud,
197
- azp: payload.azp,
198
- scope: payload.scope?.join?.(' ') ?? payload.scope,
199
- origin: payload.origin,
200
- exp: payload.exp,
201
- });
202
- }
203
- }
204
- catch {
205
- logger.debug('PP user JWT: failed to decode claims');
206
- }
207
- // Use SAP Cloud SDK to resolve the destination with per-user JWT.
208
- // The SDK handles: service token acquisition, X-User-Token header,
209
- // and per-user destination caching (keyed by destinationName + jwt).
210
- const sdkDest = await getDestination({
211
- destinationName,
212
- jwt: userJwt,
213
- useCache: true,
214
- });
215
- if (!sdkDest) {
216
- throw new Error(`Destination Service (per-user) returned no destination for '${destinationName}'`);
217
- }
218
- // Map SDK Destination → ARC-1 Destination type
219
- const dest = {
220
- Name: sdkDest.name ?? destinationName,
221
- URL: sdkDest.url ?? '',
222
- Authentication: sdkDest.authentication ?? '',
223
- ProxyType: sdkDest.proxyType ?? '',
224
- User: sdkDest.username ?? '',
225
- Password: sdkDest.password ?? '',
226
- 'sap-client': sdkDest.sapClient ?? undefined,
227
- CloudConnectorLocationId: sdkDest.cloudConnectorLocationId ?? undefined,
228
- };
229
- const tokens = {};
230
- const sdkAuthTokens = sdkDest.authTokens;
231
- // Log raw auth response for PP debugging.
232
- // Field names avoid "token" substring to prevent logger redaction.
233
- const rawEntries = sdkAuthTokens?.map((t) => ({
234
- entryType: t.type,
235
- httpHeaderKey: t.http_header?.key,
236
- hasValue: !!t.value,
237
- hasHttpHeaderValue: !!t.http_header?.value,
238
- entryError: t.error,
239
- }));
240
- logger.debug('Destination Service PP response', {
241
- destination: destinationName,
242
- authentication: dest.Authentication,
243
- proxyType: dest.ProxyType,
244
- url: dest.URL,
245
- ppEntryCount: sdkAuthTokens?.length ?? 0,
246
- ppEntries: rawEntries ?? 'NONE',
247
- });
248
- // Extract auth tokens from the SDK response
249
- if (sdkAuthTokens) {
250
- for (const token of sdkAuthTokens) {
251
- if (token.error) {
252
- logger.error('Destination Service auth token error', {
253
- destination: destinationName,
254
- tokenType: token.type,
255
- error: token.error,
256
- });
257
- const hint = destinationPpHint(token.error);
258
- const hintSuffix = hint ? ` — ${hint}` : '';
259
- throw new Error(`Destination Service auth token error for '${destinationName}': ${token.error}${hintSuffix}`);
260
- }
261
- // SAP-Connectivity-Authentication header (used by Cloud Connector for PP)
262
- if (token.http_header?.key === 'SAP-Connectivity-Authentication') {
263
- tokens.sapConnectivityAuth = token.http_header.value;
264
- logger.debug('PP: SAP-Connectivity-Authentication header extracted', {
265
- destination: destinationName,
266
- headerValueLength: token.http_header.value.length,
267
- });
268
- }
269
- // Bearer token (OAuth2UserTokenExchange / OAuth2SAMLBearerAssertion). The SAP Cloud SDK
270
- // lowercases the type ("bearer") for OAuth2UserTokenExchange and exposes the token via
271
- // `value` and/or an `Authorization` http_header. Match case-insensitively and fall back to
272
- // the header value (stripping the "Bearer " prefix). Verified live against a BTP ABAP
273
- // Environment (#301): a capital-B-only check silently dropped the token (hasBearer:false).
274
- if (token.type?.toLowerCase() === 'bearer') {
275
- tokens.bearerToken = token.value || token.http_header?.value?.replace(/^Bearer\s+/i, '');
276
- }
277
- }
278
- }
279
- else {
280
- logger.warn('Destination Service returned no authTokens — trying jwt-bearer exchange fallback', {
281
- destination: destinationName,
282
- authentication: dest.Authentication,
283
- });
284
- }
285
- // ─── PP jwt-bearer fallback (Option 2) ─────────────────────────────
286
- //
287
- // Background: The BTP Destination Service SHOULD return authTokens containing
288
- // the SAP-Connectivity-Authentication header for PrincipalPropagation destinations.
289
- // In practice, it often returns NO authTokens (empty response). This is a known
290
- // issue — the Destination Service simply omits the field.
291
- //
292
- // Workaround: We perform a jwt-bearer token exchange with the Connectivity
293
- // Service's XSUAA to verify the user JWT is valid. If the exchange succeeds,
294
- // we send the ORIGINAL user JWT as SAP-Connectivity-Authentication (Option 2
295
- // per SAP docs page 211). The Cloud Connector extracts the user identity from
296
- // this header and generates the X.509 certificate.
297
- //
298
- // Why Option 2 and not Option 1?
299
- // - Option 1 sends the EXCHANGED token as Proxy-Authorization
300
- // - The CC couldn't extract the principal from the exchanged token
301
- // (CC trace: "no principal available, injecting empty certificate")
302
- // - Option 2 sends the ORIGINAL user JWT as SAP-Connectivity-Authentication
303
- // + regular connectivity proxy token as Proxy-Authorization
304
- // - The CC successfully extracts the user email from the original JWT
305
- //
306
- // Reference: SAP BTP Connectivity docs page 209-213
307
- // https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/configure-principal-propagation-via-user-exchange-token
308
- if (!tokens.sapConnectivityAuth && dest.Authentication === 'PrincipalPropagation' && btpConfig.connectivityClientId) {
309
- logger.info('PP jwt-bearer exchange: attempting direct exchange with Connectivity Service', {
310
- destination: destinationName,
311
- connectivityUrl: btpConfig.connectivityTokenUrl,
312
- });
313
- try {
314
- // Exchange user JWT via jwt-bearer grant type with Connectivity Service credentials.
315
- // This validates the user JWT and proves we have a legitimate user token.
316
- // The exchange itself isn't used for auth — we use the original JWT instead.
317
- const exchangeResp = await fetch(btpConfig.connectivityTokenUrl, {
318
- method: 'POST',
319
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
320
- body: new URLSearchParams({
321
- grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
322
- client_id: btpConfig.connectivityClientId,
323
- client_secret: btpConfig.connectivitySecret,
324
- assertion: userJwt,
325
- token_format: 'jwt',
326
- response_type: 'token',
327
- }).toString(),
328
- });
329
- if (exchangeResp.ok) {
330
- await exchangeResp.json(); // consume response body
331
- // Option 2: Send the ORIGINAL user JWT as SAP-Connectivity-Authentication.
332
- // The CC reads this header, extracts the user identity (email), and generates
333
- // a short-lived X.509 certificate with CN=${email}. The regular connectivity
334
- // proxy token (from btpProxy.getProxyToken()) is sent as Proxy-Authorization.
335
- tokens.sapConnectivityAuth = `Bearer ${userJwt}`;
336
- logger.info('PP: using Option 2 (SAP-Connectivity-Authentication with original JWT)', {
337
- destination: destinationName,
338
- });
339
- }
340
- else {
341
- const errText = await exchangeResp.text();
342
- logger.error('PP jwt-bearer exchange: failed', {
343
- destination: destinationName,
344
- status: exchangeResp.status,
345
- error: errText.slice(0, 300),
346
- });
347
- }
348
- }
349
- catch (err) {
350
- logger.error('PP jwt-bearer exchange: error', {
351
- destination: destinationName,
352
- error: err instanceof Error ? err.message : String(err),
353
- });
354
- }
355
- }
356
- logger.info('BTP destination resolved (per-user)', {
357
- name: dest.Name,
358
- url: dest.URL,
359
- auth: dest.Authentication,
360
- hasConnectivityAuth: !!tokens.sapConnectivityAuth,
361
- hasBearer: !!tokens.bearerToken,
362
- });
363
- return { destination: dest, authTokens: tokens };
364
- }
365
- // ─── Top-Level Resolver ──────────────────────────────────────────────
366
- /**
367
- * Resolve BTP destination and connectivity proxy.
368
- * Called on startup when SAP_BTP_DESTINATION env var is set.
369
- *
370
- * Returns the resolved SAP connection config to override defaults.
371
- */
372
- export async function resolveBTPDestination(destinationName) {
373
- const btpConfig = parseVCAPServices();
374
- if (!btpConfig) {
375
- throw new Error('SAP_BTP_DESTINATION is set but VCAP_SERVICES is not available. Are you running on BTP CF?');
376
- }
377
- // Use direct fetch for startup — works with BasicAuth destinations without JWT.
378
- // The SDK's getDestination() fails for PrincipalPropagation destinations at startup
379
- // because there's no user JWT available yet.
380
- const dest = await lookupDestination(btpConfig, destinationName);
381
- const proxy = dest.ProxyType === 'OnPremise' ? createConnectivityProxy(btpConfig, dest.CloudConnectorLocationId) : null;
382
- return {
383
- url: dest.URL,
384
- username: dest.User,
385
- password: dest.Password,
386
- client: dest['sap-client'] || '100',
387
- proxy,
388
- };
389
- }
390
- /**
391
- * Get the app's public URL.
392
- *
393
- * Priority:
394
- * 1. ARC1_PUBLIC_URL env var — set this when the app is reached through a
395
- * reverse proxy on a different hostname (e.g. SAP Integration Suite API
396
- * Management). The value flows into every absolute URL the OAuth metadata
397
- * endpoints emit (issuer, authorize, token, register, revoke, resource).
398
- * May include a base-path component (e.g. https://api.example.com/arc1) —
399
- * the path is preserved verbatim.
400
- * 2. VCAP_APPLICATION.application_uris[0] — set automatically by CF, points
401
- * to the app's CF route.
402
- * 3. undefined — caller falls back to bind-host:port.
403
- *
404
- * The trailing slash, if present, is stripped so callers can do `${url}/path`
405
- * consistently.
406
- */
407
- export function getAppUrl() {
408
- const override = process.env.ARC1_PUBLIC_URL?.trim();
409
- if (override) {
410
- return override.replace(/\/$/, '');
411
- }
412
- const vcapApp = process.env.VCAP_APPLICATION;
413
- if (!vcapApp)
414
- return undefined;
415
- try {
416
- const app = JSON.parse(vcapApp);
417
- const uris = app.application_uris ?? app.uris;
418
- if (Array.isArray(uris) && uris.length > 0) {
419
- return `https://${uris[0]}`;
420
- }
421
- }
422
- catch {
423
- // Not valid JSON
424
- }
425
- return undefined;
426
- }
427
- //# sourceMappingURL=btp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"btp.js","sourceRoot":"","sources":["../../src/adt/btp.ts"],"names":[],"mappings":"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"}
@@ -1,92 +0,0 @@
1
- /**
2
- * Stateless, signed OAuth `state` codec for the XSUAA callback proxy.
3
- *
4
- * ── Why this exists (issue #214) ──────────────────────────────────────
5
- * XSUAA echoes a literal `+` (not `%2B`) for any `state` value that
6
- * contains `+` when it redirects back to the OAuth client. Standard base64
7
- * `state` values (e.g. VS Code generates `randomBytes(16).toString('base64')`)
8
- * contain `+` ~50% of the time. The receiving client parses the callback
9
- * query string with `application/x-www-form-urlencoded` semantics, where
10
- * `+` decodes to a space, so the round-tripped `state` no longer matches the
11
- * value the client generated → "State does not match" → login fails.
12
- *
13
- * ARC-1 cannot influence what XSUAA emits, and XSUAA redirects DIRECTLY to
14
- * the client today (ARC-1 is not in the return path). The only fix is to
15
- * insert ARC-1 into the return path: send XSUAA a `state` that ARC-1
16
- * controls and that is immune to the `+` bug, then re-emit the client's
17
- * ORIGINAL `state` correctly when redirecting back to the client.
18
- *
19
- * ── How this codec is immune to the `+` bug ───────────────────────────
20
- * The token is `base64url(payload) + "." + base64url(sig)`. base64url uses
21
- * the alphabet `A-Za-z0-9-_` — no `+`, no `/`. The `.` separator is an
22
- * RFC 3986 unreserved character. So the entire token is URL-safe: XSUAA has
23
- * no `+` to mangle, and Express's `+`→space query decoding is a no-op on it.
24
- * The client's real `state` (which may contain `+`) rides INSIDE the opaque
25
- * base64url payload, so it survives the XSUAA round-trip untouched.
26
- *
27
- * ── Why stateless (vs an in-memory map) ───────────────────────────────
28
- * Mirrors the StatelessDcrClientStore design (PR #212): the token carries
29
- * its own payload + HMAC signature, so any instance with the same signing
30
- * key can validate it. No in-memory map → survives `cf restart`, cell
31
- * moves, and horizontal scale-out. The signing key is derived (HKDF-style)
32
- * from the same secret the DCR store uses, with a distinct domain-separation
33
- * label so the two key spaces never overlap.
34
- *
35
- * ── Upstream tracking / when this whole module can be deleted ──────────
36
- * This is a WORKAROUND for an XSUAA bug. It can be removed ONLY when XSUAA
37
- * stops emitting a literal `+` (emits `%2B`) for `state` on the authorize
38
- * redirect. Tracking:
39
- * - arc-1 issue: https://github.com/marianfoo/arc-1/issues/214
40
- * - XSUAA root cause: no public SAP Note as of 2026-06; the `+`→literal
41
- * echo is the actual defect and the only thing whose
42
- * fix makes this module removable.
43
- * - VS Code (client): https://github.com/microsoft/vscode/issues/314715
44
- * asks VS Code to use base64url `state`. If accepted it
45
- * fixes the VS Code SYMPTOM only — other MCP clients
46
- * (Cursor, claude.ai, Copilot Studio, …) still send
47
- * base64 `state` containing `+`, so the callback proxy
48
- * stays until the XSUAA-side fix lands. Do NOT delete
49
- * this module just because vscode#314715 closes.
50
- * To verify whether the XSUAA bug is gone, re-run the issue #214 spectrum
51
- * reproducer (see the issue thread) against the target XSUAA tenant.
52
- */
53
- export type DecodeResult = {
54
- kind: 'ok';
55
- clientState?: string;
56
- clientRedirectUri: string;
57
- clientId: string;
58
- } | {
59
- kind: 'error';
60
- reason: 'malformed' | 'bad_signature' | 'invalid_payload' | 'expired';
61
- };
62
- /**
63
- * Signs and verifies OAuth `state` tokens for the XSUAA callback proxy.
64
- */
65
- export declare class OAuthStateCodec {
66
- private readonly hmacKey;
67
- private readonly ttlSeconds;
68
- constructor(signingSecret: string, opts?: {
69
- ttlSeconds?: number;
70
- });
71
- /**
72
- * Encode a URL-safe, signed state token. The returned value is safe to put
73
- * in a query string and round-trip through XSUAA (no `+`, no `/`).
74
- *
75
- * @param input.now Injectable clock (epoch ms) for deterministic tests.
76
- */
77
- encode(input: {
78
- clientState?: string;
79
- clientRedirectUri: string;
80
- clientId: string;
81
- now?: number;
82
- }): string;
83
- /**
84
- * Decode and verify a state token. Never throws — returns a typed result.
85
- *
86
- * @param now Injectable clock (epoch ms) for deterministic tests.
87
- */
88
- decode(token: string, now?: number): DecodeResult;
89
- private sign;
90
- private verifySignature;
91
- }
92
- //# sourceMappingURL=oauth-state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oauth-state.d.ts","sourceRoot":"","sources":["../../src/server/oauth-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAsCH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,eAAe,GAAG,iBAAiB,GAAG,SAAS,CAAA;CAAE,CAAC;AAE7F;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,aAAa,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO;IAUrE;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IAe1G;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,YAAY;IA2B7D,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,eAAe;CAQxB"}