@sap-ux/backend-proxy-middleware 0.10.2 → 0.10.4

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.
@@ -1,13 +1,14 @@
1
- import type { ServerOptions } from 'http-proxy';
2
- import type { RequestHandler, Options } from 'http-proxy-middleware';
3
- import type { ClientRequest, IncomingMessage, ServerResponse } from 'http';
4
1
  import { ToolsLogger, type Logger } from '@sap-ux/logger';
2
+ import type { ClientRequest, IncomingMessage, ServerResponse } from 'http';
3
+ import type { ServerOptions } from 'http-proxy';
4
+ import type { Options, RequestHandler } from 'http-proxy-middleware';
5
5
  import type { BackendConfig, DestinationBackendConfig } from './types';
6
6
  import type { BackendSystem } from '@sap-ux/store';
7
- import type { Url } from 'node:url';
8
- import type { Socket } from 'node:net';
9
- import type { Request } from 'express';
7
+ import { AuthenticationType } from '@sap-ux/store';
10
8
  import type connect from 'connect';
9
+ import type { Request } from 'express';
10
+ import type { Socket } from 'node:net';
11
+ import type { Url } from 'node:url';
11
12
  export type EnhancedIncomingMessage = (IncomingMessage & Pick<Request, 'originalUrl'>) | connect.IncomingMessage;
12
13
  /**
13
14
  * Collection of custom event handler for the proxy.
@@ -99,12 +100,12 @@ export declare function enhanceConfigsForDestination(proxyOptions: Options & {
99
100
  *
100
101
  * @param proxyOptions reference to a proxy options object that the function will enhance
101
102
  * @param system backend system information (most likely) read from the store
102
- * @param oAuthRequired if true then the OAuth flow is triggered to get cookies
103
+ * @param authType determines the authentication protocol to be used
103
104
  * @param tokenChangedCallback function to call if a new refreshToken is available
104
105
  */
105
106
  export declare function enhanceConfigForSystem(proxyOptions: Options & {
106
107
  headers: object;
107
- }, system: BackendSystem | undefined, oAuthRequired: boolean | undefined, tokenChangedCallback: (refreshToken?: string) => void): Promise<void>;
108
+ }, system: BackendSystem | undefined, authType: AuthenticationType, tokenChangedCallback: (refreshToken?: string) => void): Promise<void>;
108
109
  /**
109
110
  * Generate options for the proxy middleware based on the input.
110
111
  *
@@ -10,17 +10,17 @@ exports.enhanceConfigsForDestination = enhanceConfigsForDestination;
10
10
  exports.enhanceConfigForSystem = enhanceConfigForSystem;
11
11
  exports.generateProxyMiddlewareOptions = generateProxyMiddlewareOptions;
12
12
  exports.createProxy = createProxy;
13
- const https_proxy_agent_1 = require("https-proxy-agent");
14
- const http_proxy_middleware_1 = require("http-proxy-middleware");
15
- const i18next_1 = __importDefault(require("i18next"));
16
- const logger_1 = require("@sap-ux/logger");
17
13
  const axios_extension_1 = require("@sap-ux/axios-extension");
18
14
  const btp_utils_1 = require("@sap-ux/btp-utils");
15
+ const logger_1 = require("@sap-ux/logger");
16
+ const http_proxy_middleware_1 = require("http-proxy-middleware");
17
+ const https_proxy_agent_1 = require("https-proxy-agent");
18
+ const i18next_1 = __importDefault(require("i18next"));
19
19
  const i18n_json_1 = __importDefault(require("./i18n.json"));
20
20
  const store_1 = require("@sap-ux/store");
21
- const config_1 = require("./config");
22
- const bsp_1 = require("../ext/bsp");
23
21
  const proxy_from_env_1 = require("proxy-from-env");
22
+ const bsp_1 = require("../ext/bsp");
23
+ const config_1 = require("./config");
24
24
  /**
25
25
  * Collection of custom event handler for the proxy.
26
26
  */
@@ -239,11 +239,11 @@ async function enhanceConfigsForDestination(proxyOptions, backend) {
239
239
  *
240
240
  * @param proxyOptions reference to a proxy options object that the function will enhance
241
241
  * @param system backend system information (most likely) read from the store
242
- * @param oAuthRequired if true then the OAuth flow is triggered to get cookies
242
+ * @param authType determines the authentication protocol to be used
243
243
  * @param tokenChangedCallback function to call if a new refreshToken is available
244
244
  */
245
- async function enhanceConfigForSystem(proxyOptions, system, oAuthRequired, tokenChangedCallback) {
246
- if (oAuthRequired) {
245
+ async function enhanceConfigForSystem(proxyOptions, system, authType, tokenChangedCallback) {
246
+ if (authType === store_1.AuthenticationType.OAuth2RefreshToken) {
247
247
  if (system?.serviceKeys) {
248
248
  const provider = (0, axios_extension_1.createForAbapOnCloud)({
249
249
  environment: axios_extension_1.AbapCloudEnvironment.Standalone,
@@ -255,10 +255,10 @@ async function enhanceConfigForSystem(proxyOptions, system, oAuthRequired, token
255
255
  await provider.getAtoInfo();
256
256
  }
257
257
  else {
258
- throw new Error('Cannot connect to ABAP Environment on BTP without service keys.');
258
+ throw new Error('Cannot connect to ABAP Environment on BTP using OAuth without service keys.');
259
259
  }
260
260
  }
261
- else if (system?.authenticationType === store_1.AuthenticationType.ReentranceTicket) {
261
+ else if (system && authType === store_1.AuthenticationType.ReentranceTicket) {
262
262
  const provider = (0, axios_extension_1.createForAbapOnCloud)({
263
263
  ignoreCertErrors: proxyOptions.secure === false,
264
264
  environment: axios_extension_1.AbapCloudEnvironment.EmbeddedSteampunk,
@@ -309,33 +309,7 @@ async function generateProxyMiddlewareOptions(backend, options = {}, logger = ne
309
309
  }
310
310
  }
311
311
  else {
312
- const localBackend = backend;
313
- // check if system credentials are stored in the store
314
- try {
315
- const systemStore = await (0, store_1.getService)({ logger, entityName: 'system' });
316
- const system = (await systemStore.read(new store_1.BackendSystemKey({ url: localBackend.url, client: localBackend.client }))) ?? {
317
- name: '<unknown>',
318
- url: localBackend.url,
319
- authenticationType: localBackend.authenticationType
320
- };
321
- await enhanceConfigForSystem(proxyOptions, system, backend.scp, (refreshToken, accessToken) => {
322
- if (refreshToken) {
323
- logger.info('Updating refresh token for: ' + localBackend.url);
324
- systemStore.write({ ...system, refreshToken }).catch((error) => logger.error(error));
325
- }
326
- if (accessToken) {
327
- logger.info('Setting access token');
328
- proxyOptions.headers['authorization'] = `bearer ${accessToken}`;
329
- }
330
- else {
331
- logger.warn('Setting of access token failed.');
332
- }
333
- });
334
- }
335
- catch (error) {
336
- logger.warn('Accessing the credentials store failed.');
337
- logger.debug(error);
338
- }
312
+ await updateProxyConfigFromStore(backend, logger, proxyOptions);
339
313
  }
340
314
  if (!proxyOptions.auth && process.env.FIORI_TOOLS_USER && process.env.FIORI_TOOLS_PASSWORD) {
341
315
  proxyOptions.auth = `${process.env.FIORI_TOOLS_USER}:${process.env.FIORI_TOOLS_PASSWORD}`;
@@ -361,6 +335,44 @@ async function generateProxyMiddlewareOptions(backend, options = {}, logger = ne
361
335
  logger.info(`Backend proxy created for ${proxyOptions.target}`);
362
336
  return proxyOptions;
363
337
  }
338
+ /**
339
+ * Determine the correct authentication configuration for connections from a non-BAS platform.
340
+ *
341
+ * @param backend the backend config loaded from the yaml config
342
+ * @param logger a logger instance
343
+ * @param proxyOptions additional proxy header, request and response settings
344
+ */
345
+ async function updateProxyConfigFromStore(backend, logger, proxyOptions) {
346
+ const localBackend = backend;
347
+ // check if system credentials are stored in the store
348
+ try {
349
+ const systemStore = await (0, store_1.getService)({ logger, entityName: 'system' });
350
+ const system = (await systemStore.read(new store_1.BackendSystemKey({ url: localBackend.url, client: localBackend.client }))) ?? {
351
+ name: '<unknown>',
352
+ url: localBackend.url,
353
+ authenticationType: localBackend.authenticationType
354
+ };
355
+ // Auth type is determined from app config as we may have multiple stored systems with the same url/client using different auth types
356
+ await enhanceConfigForSystem(proxyOptions, system, localBackend.authenticationType ??
357
+ (localBackend.scp ? store_1.AuthenticationType.OAuth2RefreshToken : store_1.AuthenticationType.Basic), (refreshToken, accessToken) => {
358
+ if (refreshToken) {
359
+ logger.info('Updating refresh token for: ' + localBackend.url);
360
+ systemStore.write({ ...system, refreshToken }).catch((error) => logger.error(error));
361
+ }
362
+ if (accessToken) {
363
+ logger.info('Setting access token');
364
+ proxyOptions.headers['authorization'] = `bearer ${accessToken}`;
365
+ }
366
+ else {
367
+ logger.warn('Setting of access token failed.');
368
+ }
369
+ });
370
+ }
371
+ catch (error) {
372
+ logger.warn('Accessing the credentials store failed.');
373
+ logger.debug(error);
374
+ }
375
+ }
364
376
  /**
365
377
  * Generate an instance of the proxy middleware based on the input.
366
378
  *
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "bugs": {
10
10
  "url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Abackend-proxy-middleware"
11
11
  },
12
- "version": "0.10.2",
12
+ "version": "0.10.4",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -28,10 +28,10 @@
28
28
  "i18next": "25.3.0",
29
29
  "prompts": "2.4.2",
30
30
  "proxy-from-env": "1.1.0",
31
- "@sap-ux/axios-extension": "1.22.10",
31
+ "@sap-ux/axios-extension": "1.23.0",
32
32
  "@sap-ux/btp-utils": "1.1.4",
33
33
  "@sap-ux/logger": "0.7.0",
34
- "@sap-ux/store": "1.1.5"
34
+ "@sap-ux/store": "1.2.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/express": "4.17.21",