@sap-ux/backend-proxy-middleware 0.7.41 → 0.8.1
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/dist/base/proxy.js +144 -165
- package/dist/ext/bsp.js +62 -75
- package/dist/middleware.js +9 -16
- package/package.json +5 -5
package/dist/base/proxy.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -37,8 +28,7 @@ exports.ProxyEventHandlers = {
|
|
|
37
28
|
* @param _options (not used)
|
|
38
29
|
*/
|
|
39
30
|
onProxyReq(proxyReq, _req, _res, _options) {
|
|
40
|
-
|
|
41
|
-
if (((_a = proxyReq.path) === null || _a === void 0 ? void 0 : _a.includes('Fiorilaunchpad.html')) && !proxyReq.headersSent) {
|
|
31
|
+
if (proxyReq.path?.includes('Fiorilaunchpad.html') && !proxyReq.headersSent) {
|
|
42
32
|
proxyReq.setHeader('accept-encoding', '*');
|
|
43
33
|
}
|
|
44
34
|
},
|
|
@@ -50,9 +40,8 @@ exports.ProxyEventHandlers = {
|
|
|
50
40
|
* @param _res (not used)
|
|
51
41
|
*/
|
|
52
42
|
onProxyRes(proxyRes, _req, _res) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (header === null || header === void 0 ? void 0 : header.length) {
|
|
43
|
+
const header = proxyRes?.headers?.['set-cookie'];
|
|
44
|
+
if (header?.length) {
|
|
56
45
|
for (let i = header.length - 1; i >= 0; i--) {
|
|
57
46
|
const cookie = header[i].replace(/\s?Domain=[^\s]*\s?|\s?SameSite=[^\s]*\s?|\s?Secure[^\s]*\s?|\s?Partitioned[^\s]*\s?/gi, '');
|
|
58
47
|
header[i] = cookie;
|
|
@@ -70,8 +59,7 @@ exports.ProxyEventHandlers = {
|
|
|
70
59
|
* @param _target (not used)
|
|
71
60
|
*/
|
|
72
61
|
function proxyErrorHandler(err, req, logger, _res, _target) {
|
|
73
|
-
|
|
74
|
-
if (err && ((_a = err.stack) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== 'error') {
|
|
62
|
+
if (err && err.stack?.toLowerCase() !== 'error') {
|
|
75
63
|
let error;
|
|
76
64
|
if (err.code === 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY') {
|
|
77
65
|
error = new Error(i18next_1.default.t('error.sslProxy'));
|
|
@@ -98,19 +86,17 @@ exports.proxyErrorHandler = proxyErrorHandler;
|
|
|
98
86
|
* @param logger - logger to report errors
|
|
99
87
|
* @returns {*} {(Promise<string | undefined>)} - ApiHubKey
|
|
100
88
|
*/
|
|
101
|
-
function getApiHubKey(logger) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return apiHubKey;
|
|
113
|
-
});
|
|
89
|
+
async function getApiHubKey(logger) {
|
|
90
|
+
let apiHubKey = process.env.API_HUB_API_KEY;
|
|
91
|
+
if (!apiHubKey && !(0, btp_utils_1.isAppStudio)()) {
|
|
92
|
+
const apiHubStore = (await (0, store_1.getService)({
|
|
93
|
+
logger,
|
|
94
|
+
entityName: 'api-hub'
|
|
95
|
+
}));
|
|
96
|
+
const apiHubSettings = await apiHubStore.read();
|
|
97
|
+
apiHubKey = apiHubSettings ? apiHubSettings.apiKey : undefined;
|
|
98
|
+
}
|
|
99
|
+
return apiHubKey;
|
|
114
100
|
}
|
|
115
101
|
/**
|
|
116
102
|
* Collection of path rewrite functions.
|
|
@@ -183,20 +169,18 @@ exports.PathRewriters = {
|
|
|
183
169
|
/**
|
|
184
170
|
* Initialize i18next with the translations for this module.
|
|
185
171
|
*/
|
|
186
|
-
function initI18n() {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
ns: [ns]
|
|
199
|
-
});
|
|
172
|
+
async function initI18n() {
|
|
173
|
+
const ns = 'backend-proxy-middleware';
|
|
174
|
+
await i18next_1.default.init({
|
|
175
|
+
resources: {
|
|
176
|
+
en: {
|
|
177
|
+
[ns]: i18n_json_1.default
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
lng: 'en',
|
|
181
|
+
fallbackLng: 'en',
|
|
182
|
+
defaultNS: ns,
|
|
183
|
+
ns: [ns]
|
|
200
184
|
});
|
|
201
185
|
}
|
|
202
186
|
exports.initI18n = initI18n;
|
|
@@ -206,28 +190,25 @@ exports.initI18n = initI18n;
|
|
|
206
190
|
* @param proxyOptions reference to a proxy options object that the function will enhance
|
|
207
191
|
* @param backend reference to the backend configuration that the the function may enhance
|
|
208
192
|
*/
|
|
209
|
-
function enhanceConfigsForDestination(proxyOptions, backend) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
proxyOptions.
|
|
213
|
-
|
|
214
|
-
|
|
193
|
+
async function enhanceConfigsForDestination(proxyOptions, backend) {
|
|
194
|
+
proxyOptions.target = (0, btp_utils_1.getDestinationUrlForAppStudio)(backend.destination);
|
|
195
|
+
if (backend.destinationInstance) {
|
|
196
|
+
proxyOptions.headers[btp_utils_1.BAS_DEST_INSTANCE_CRED_HEADER] = await (0, btp_utils_1.getCredentialsForDestinationService)(backend.destinationInstance);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const destinations = await (0, btp_utils_1.listDestinations)();
|
|
200
|
+
const destination = destinations[backend.destination];
|
|
201
|
+
if (destination) {
|
|
202
|
+
// in case of a full url destination remove the path defined in the destination from the forwarded call
|
|
203
|
+
if ((0, btp_utils_1.isFullUrlDestination)(destination)) {
|
|
204
|
+
backend.path = new URL(destination.Host).pathname.replace(/\/$/, '');
|
|
205
|
+
backend.pathReplace = backend.pathReplace ?? '/';
|
|
206
|
+
}
|
|
215
207
|
}
|
|
216
208
|
else {
|
|
217
|
-
|
|
218
|
-
const destination = destinations[backend.destination];
|
|
219
|
-
if (destination) {
|
|
220
|
-
// in case of a full url destination remove the path defined in the destination from the forwarded call
|
|
221
|
-
if ((0, btp_utils_1.isFullUrlDestination)(destination)) {
|
|
222
|
-
backend.path = new URL(destination.Host).pathname.replace(/\/$/, '');
|
|
223
|
-
backend.pathReplace = (_a = backend.pathReplace) !== null && _a !== void 0 ? _a : '/';
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
throw new Error();
|
|
228
|
-
}
|
|
209
|
+
throw new Error();
|
|
229
210
|
}
|
|
230
|
-
}
|
|
211
|
+
}
|
|
231
212
|
}
|
|
232
213
|
exports.enhanceConfigsForDestination = enhanceConfigsForDestination;
|
|
233
214
|
/**
|
|
@@ -238,39 +219,37 @@ exports.enhanceConfigsForDestination = enhanceConfigsForDestination;
|
|
|
238
219
|
* @param oAuthRequired if true then the OAuth flow is triggered to get cookies
|
|
239
220
|
* @param tokenChangedCallback function to call if a new refreshToken is available
|
|
240
221
|
*/
|
|
241
|
-
function enhanceConfigForSystem(proxyOptions, system, oAuthRequired, tokenChangedCallback) {
|
|
242
|
-
|
|
243
|
-
if (
|
|
244
|
-
if (system === null || system === void 0 ? void 0 : system.serviceKeys) {
|
|
245
|
-
const provider = (0, axios_extension_1.createForAbapOnCloud)({
|
|
246
|
-
environment: axios_extension_1.AbapCloudEnvironment.Standalone,
|
|
247
|
-
service: system.serviceKeys,
|
|
248
|
-
refreshToken: system.refreshToken,
|
|
249
|
-
refreshTokenChangedCb: tokenChangedCallback
|
|
250
|
-
});
|
|
251
|
-
// sending a request to the backend to get token
|
|
252
|
-
yield provider.getAtoInfo();
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
throw new Error('Cannot connect to ABAP Environment on BTP without service keys.');
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
else if ((system === null || system === void 0 ? void 0 : system.authenticationType) === store_1.AuthenticationType.ReentranceTicket) {
|
|
222
|
+
async function enhanceConfigForSystem(proxyOptions, system, oAuthRequired, tokenChangedCallback) {
|
|
223
|
+
if (oAuthRequired) {
|
|
224
|
+
if (system?.serviceKeys) {
|
|
259
225
|
const provider = (0, axios_extension_1.createForAbapOnCloud)({
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
226
|
+
environment: axios_extension_1.AbapCloudEnvironment.Standalone,
|
|
227
|
+
service: system.serviceKeys,
|
|
228
|
+
refreshToken: system.refreshToken,
|
|
229
|
+
refreshTokenChangedCb: tokenChangedCallback
|
|
263
230
|
});
|
|
264
|
-
// sending a request to the backend to get
|
|
265
|
-
|
|
266
|
-
if (ato) {
|
|
267
|
-
proxyOptions.headers['cookie'] = provider.cookies.toString();
|
|
268
|
-
}
|
|
231
|
+
// sending a request to the backend to get token
|
|
232
|
+
await provider.getAtoInfo();
|
|
269
233
|
}
|
|
270
|
-
else
|
|
271
|
-
|
|
234
|
+
else {
|
|
235
|
+
throw new Error('Cannot connect to ABAP Environment on BTP without service keys.');
|
|
272
236
|
}
|
|
273
|
-
}
|
|
237
|
+
}
|
|
238
|
+
else if (system?.authenticationType === store_1.AuthenticationType.ReentranceTicket) {
|
|
239
|
+
const provider = (0, axios_extension_1.createForAbapOnCloud)({
|
|
240
|
+
ignoreCertErrors: proxyOptions.secure === false,
|
|
241
|
+
environment: axios_extension_1.AbapCloudEnvironment.EmbeddedSteampunk,
|
|
242
|
+
url: system.url
|
|
243
|
+
});
|
|
244
|
+
// sending a request to the backend to get cookies
|
|
245
|
+
const ato = await provider.getAtoInfo();
|
|
246
|
+
if (ato) {
|
|
247
|
+
proxyOptions.headers['cookie'] = provider.cookies.toString();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else if (system?.username && system.password) {
|
|
251
|
+
proxyOptions.auth = `${system.username}:${system.password}`;
|
|
252
|
+
}
|
|
274
253
|
}
|
|
275
254
|
exports.enhanceConfigForSystem = enhanceConfigForSystem;
|
|
276
255
|
/**
|
|
@@ -281,80 +260,82 @@ exports.enhanceConfigForSystem = enhanceConfigForSystem;
|
|
|
281
260
|
* @param logger optional logger instance
|
|
282
261
|
* @returns options for the http-proxy-middleware
|
|
283
262
|
*/
|
|
284
|
-
function generateProxyMiddlewareOptions(backend, options = {}, logger = new logger_1.ToolsLogger()) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const localBackend = backend;
|
|
306
|
-
// check if system credentials are stored in the store
|
|
307
|
-
try {
|
|
308
|
-
const systemStore = yield (0, store_1.getService)({ logger, entityName: 'system' });
|
|
309
|
-
const system = (_b = (yield systemStore.read(new store_1.BackendSystemKey({ url: localBackend.url, client: localBackend.client })))) !== null && _b !== void 0 ? _b : {
|
|
310
|
-
name: '<unknown>',
|
|
311
|
-
url: localBackend.url,
|
|
312
|
-
authenticationType: localBackend.authenticationType
|
|
313
|
-
};
|
|
314
|
-
yield enhanceConfigForSystem(proxyOptions, system, backend.scp, (refreshToken, accessToken) => {
|
|
315
|
-
if (refreshToken) {
|
|
316
|
-
logger.info('Updating refresh token for: ' + localBackend.url);
|
|
317
|
-
systemStore.write(Object.assign(Object.assign({}, system), { refreshToken })).catch((error) => logger.error(error));
|
|
318
|
-
}
|
|
319
|
-
if (accessToken) {
|
|
320
|
-
logger.info('Setting access token');
|
|
321
|
-
proxyOptions.headers['authorization'] = `bearer ${accessToken}`;
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
logger.warn('Setting of access token failed.');
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
catch (error) {
|
|
329
|
-
logger.warn('Accessing the credentials store failed.');
|
|
330
|
-
logger.debug(error);
|
|
331
|
-
}
|
|
263
|
+
async function generateProxyMiddlewareOptions(backend, options = {}, logger = new logger_1.ToolsLogger()) {
|
|
264
|
+
// add required options
|
|
265
|
+
const proxyOptions = {
|
|
266
|
+
headers: {},
|
|
267
|
+
...exports.ProxyEventHandlers,
|
|
268
|
+
onError: (err, req, res, target) => {
|
|
269
|
+
proxyErrorHandler(err, req, logger, res, target);
|
|
270
|
+
},
|
|
271
|
+
...options
|
|
272
|
+
};
|
|
273
|
+
proxyOptions.changeOrigin = true;
|
|
274
|
+
proxyOptions.logProvider = () => logger;
|
|
275
|
+
// always set the target to the url provided in yaml
|
|
276
|
+
proxyOptions.target = backend.url;
|
|
277
|
+
// overwrite url if running in AppStudio
|
|
278
|
+
if ((0, btp_utils_1.isAppStudio)()) {
|
|
279
|
+
const destBackend = backend;
|
|
280
|
+
destBackend.destination = destBackend.destination ?? process.env.FIORI_TOOLS_DESTINATION;
|
|
281
|
+
if (destBackend.destination) {
|
|
282
|
+
await enhanceConfigsForDestination(proxyOptions, destBackend);
|
|
283
|
+
logger.info('Using destination: ' + destBackend.destination);
|
|
332
284
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
const localBackend = backend;
|
|
288
|
+
// check if system credentials are stored in the store
|
|
289
|
+
try {
|
|
290
|
+
const systemStore = await (0, store_1.getService)({ logger, entityName: 'system' });
|
|
291
|
+
const system = (await systemStore.read(new store_1.BackendSystemKey({ url: localBackend.url, client: localBackend.client }))) ?? {
|
|
292
|
+
name: '<unknown>',
|
|
293
|
+
url: localBackend.url,
|
|
294
|
+
authenticationType: localBackend.authenticationType
|
|
295
|
+
};
|
|
296
|
+
await enhanceConfigForSystem(proxyOptions, system, backend.scp, (refreshToken, accessToken) => {
|
|
297
|
+
if (refreshToken) {
|
|
298
|
+
logger.info('Updating refresh token for: ' + localBackend.url);
|
|
299
|
+
systemStore.write({ ...system, refreshToken }).catch((error) => logger.error(error));
|
|
300
|
+
}
|
|
301
|
+
if (accessToken) {
|
|
302
|
+
logger.info('Setting access token');
|
|
303
|
+
proxyOptions.headers['authorization'] = `bearer ${accessToken}`;
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
logger.warn('Setting of access token failed.');
|
|
307
|
+
}
|
|
308
|
+
});
|
|
345
309
|
}
|
|
346
|
-
|
|
347
|
-
|
|
310
|
+
catch (error) {
|
|
311
|
+
logger.warn('Accessing the credentials store failed.');
|
|
312
|
+
logger.debug(error);
|
|
348
313
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
314
|
+
}
|
|
315
|
+
if (!proxyOptions.auth && process.env.FIORI_TOOLS_USER && process.env.FIORI_TOOLS_PASSWORD) {
|
|
316
|
+
proxyOptions.auth = `${process.env.FIORI_TOOLS_USER}:${process.env.FIORI_TOOLS_PASSWORD}`;
|
|
317
|
+
}
|
|
318
|
+
proxyOptions.pathRewrite = exports.PathRewriters.getPathRewrite(backend, logger);
|
|
319
|
+
if (backend.bsp) {
|
|
320
|
+
await (0, bsp_1.addOptionsForEmbeddedBSP)(backend.bsp, proxyOptions, logger);
|
|
321
|
+
}
|
|
322
|
+
if (backend.apiHub) {
|
|
323
|
+
const apiHubKey = await getApiHubKey(logger);
|
|
324
|
+
if (apiHubKey) {
|
|
325
|
+
proxyOptions.headers['apikey'] = apiHubKey;
|
|
354
326
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
327
|
+
}
|
|
328
|
+
if (!proxyOptions.target) {
|
|
329
|
+
throw new Error(`Unable to determine target from configuration:\n${JSON.stringify(backend, null, 2)}`);
|
|
330
|
+
}
|
|
331
|
+
// update proxy config with values coming from args or ui5.yaml
|
|
332
|
+
(0, config_1.updateProxyEnv)(backend.proxy);
|
|
333
|
+
backend.proxy = (0, proxy_from_env_1.getProxyForUrl)(proxyOptions.target);
|
|
334
|
+
if (backend.proxy) {
|
|
335
|
+
proxyOptions.agent = new https_proxy_agent_1.HttpsProxyAgent(backend.proxy);
|
|
336
|
+
}
|
|
337
|
+
logger.info(`Backend proxy created for ${proxyOptions.target} ${backend.path ? backend.path : ''}`);
|
|
338
|
+
return proxyOptions;
|
|
358
339
|
}
|
|
359
340
|
exports.generateProxyMiddlewareOptions = generateProxyMiddlewareOptions;
|
|
360
341
|
/**
|
|
@@ -365,10 +346,8 @@ exports.generateProxyMiddlewareOptions = generateProxyMiddlewareOptions;
|
|
|
365
346
|
* @param logger optional logger instance
|
|
366
347
|
* @returns an instance of http-proxy-middleware
|
|
367
348
|
*/
|
|
368
|
-
function createProxy(backend, options, logger) {
|
|
369
|
-
return
|
|
370
|
-
return (0, http_proxy_middleware_1.createProxyMiddleware)(yield generateProxyMiddlewareOptions(backend, options, logger));
|
|
371
|
-
});
|
|
349
|
+
async function createProxy(backend, options, logger) {
|
|
350
|
+
return (0, http_proxy_middleware_1.createProxyMiddleware)(await generateProxyMiddlewareOptions(backend, options, logger));
|
|
372
351
|
}
|
|
373
352
|
exports.createProxy = createProxy;
|
|
374
353
|
//# sourceMappingURL=proxy.js.map
|
package/dist/ext/bsp.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -34,58 +25,56 @@ exports.convertAppDescriptorToManifest = convertAppDescriptorToManifest;
|
|
|
34
25
|
* @param log logger to report info to the user
|
|
35
26
|
* @returns prompted user and password serialized for a basic auth header
|
|
36
27
|
*/
|
|
37
|
-
function promptUserPass(log) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
message: `${(0, chalk_1.cyan)(i18next_1.default.t('info.authNeeded'))}\n\n`
|
|
45
|
-
}
|
|
46
|
-
]);
|
|
47
|
-
if (!authNeeded) {
|
|
48
|
-
return undefined;
|
|
28
|
+
async function promptUserPass(log) {
|
|
29
|
+
if ((0, btp_utils_1.isAppStudio)()) {
|
|
30
|
+
const { authNeeded } = await (0, prompts_1.default)([
|
|
31
|
+
{
|
|
32
|
+
type: 'confirm',
|
|
33
|
+
name: 'authNeeded',
|
|
34
|
+
message: `${(0, chalk_1.cyan)(i18next_1.default.t('info.authNeeded'))}\n\n`
|
|
49
35
|
}
|
|
36
|
+
]);
|
|
37
|
+
if (!authNeeded) {
|
|
38
|
+
return undefined;
|
|
50
39
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
log.info((0, chalk_1.yellow)(i18next_1.default.t('info.credentialsRequiredForFLP')));
|
|
43
|
+
}
|
|
44
|
+
const { username, password } = await (0, prompts_1.default)([
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
name: 'username',
|
|
48
|
+
message: `${(0, chalk_1.cyan)(i18next_1.default.t('info.username'))}\n\n`,
|
|
49
|
+
validate: (value) => {
|
|
50
|
+
if (!value?.trim()) {
|
|
51
|
+
return `${i18next_1.default.t('error.emptyUsername')}`;
|
|
66
52
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
type: 'password',
|
|
70
|
-
name: 'password',
|
|
71
|
-
message: `${(0, chalk_1.cyan)(i18next_1.default.t('info.password'))}\n\n`,
|
|
72
|
-
validate: (value) => {
|
|
73
|
-
if (!(value === null || value === void 0 ? void 0 : value.trim())) {
|
|
74
|
-
return `${i18next_1.default.t('error.emptyPassword')}`;
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
53
|
+
else {
|
|
54
|
+
return true;
|
|
79
55
|
}
|
|
80
56
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
type: 'password',
|
|
60
|
+
name: 'password',
|
|
61
|
+
message: `${(0, chalk_1.cyan)(i18next_1.default.t('info.password'))}\n\n`,
|
|
62
|
+
validate: (value) => {
|
|
63
|
+
if (!value?.trim()) {
|
|
64
|
+
return `${i18next_1.default.t('error.emptyPassword')}`;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
85
69
|
}
|
|
86
|
-
}
|
|
87
|
-
|
|
70
|
+
}
|
|
71
|
+
], {
|
|
72
|
+
onCancel: () => {
|
|
73
|
+
log.info((0, chalk_1.yellow)(i18next_1.default.t('info.operationAborted')));
|
|
74
|
+
return process.exit(1);
|
|
75
|
+
}
|
|
88
76
|
});
|
|
77
|
+
return `${username}:${password}`;
|
|
89
78
|
}
|
|
90
79
|
exports.promptUserPass = promptUserPass;
|
|
91
80
|
/**
|
|
@@ -95,30 +84,28 @@ exports.promptUserPass = promptUserPass;
|
|
|
95
84
|
* @param proxyOptions existing http-proxy-middleware options
|
|
96
85
|
* @param logger logger to report info to the user
|
|
97
86
|
*/
|
|
98
|
-
function addOptionsForEmbeddedBSP(bspPath, proxyOptions, logger) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return req.protocol + '://' + req.headers.host;
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
return undefined;
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
if (proxyOptions.pathRewrite) {
|
|
111
|
-
const oldRewrite = proxyOptions.pathRewrite;
|
|
112
|
-
const appDescrRewrite = convertAppDescriptorToManifest(bspPath);
|
|
113
|
-
proxyOptions.pathRewrite = (path) => appDescrRewrite(oldRewrite(path));
|
|
87
|
+
async function addOptionsForEmbeddedBSP(bspPath, proxyOptions, logger) {
|
|
88
|
+
const regex = new RegExp('(' + bspPath + '/manifest\\.appdescr\\b)');
|
|
89
|
+
proxyOptions.router = (req) => {
|
|
90
|
+
// redirects the request for manifest.appdescr to localhost
|
|
91
|
+
if (req.path.match(regex)) {
|
|
92
|
+
return req.protocol + '://' + req.headers.host;
|
|
114
93
|
}
|
|
115
94
|
else {
|
|
116
|
-
|
|
95
|
+
return undefined;
|
|
117
96
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
97
|
+
};
|
|
98
|
+
if (proxyOptions.pathRewrite) {
|
|
99
|
+
const oldRewrite = proxyOptions.pathRewrite;
|
|
100
|
+
const appDescrRewrite = convertAppDescriptorToManifest(bspPath);
|
|
101
|
+
proxyOptions.pathRewrite = (path) => appDescrRewrite(oldRewrite(path));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
proxyOptions.pathRewrite = convertAppDescriptorToManifest(bspPath);
|
|
105
|
+
}
|
|
106
|
+
if (!proxyOptions.auth) {
|
|
107
|
+
proxyOptions.auth = await promptUserPass(logger);
|
|
108
|
+
}
|
|
122
109
|
}
|
|
123
110
|
exports.addOptionsForEmbeddedBSP = addOptionsForEmbeddedBSP;
|
|
124
111
|
//# sourceMappingURL=bsp.js.map
|
package/dist/middleware.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -39,20 +30,22 @@ function formatProxyForLogging(proxy) {
|
|
|
39
30
|
* @param params.options configuration options
|
|
40
31
|
* @returns {*} {(Promise<RequestHandler>)}
|
|
41
32
|
*/
|
|
42
|
-
module.exports = ({ options }) =>
|
|
43
|
-
var _a;
|
|
33
|
+
module.exports = async ({ options }) => {
|
|
44
34
|
const logger = new logger_1.ToolsLogger({
|
|
45
35
|
transports: [new logger_1.UI5ToolingTransport({ moduleName: 'backend-proxy-middleware' })]
|
|
46
36
|
});
|
|
47
|
-
|
|
37
|
+
await (0, proxy_1.initI18n)();
|
|
48
38
|
dotenv_1.default.config();
|
|
49
39
|
const backend = options.configuration.backend;
|
|
50
|
-
const configOptions =
|
|
40
|
+
const configOptions = options.configuration.options ?? {};
|
|
51
41
|
configOptions.secure = configOptions.secure !== undefined ? !!configOptions.secure : true;
|
|
52
42
|
try {
|
|
53
|
-
const proxyOptions =
|
|
43
|
+
const proxyOptions = await (0, proxy_1.generateProxyMiddlewareOptions)(options.configuration.backend, configOptions, logger);
|
|
54
44
|
const proxyFn = (0, http_proxy_middleware_1.createProxyMiddleware)(proxyOptions);
|
|
55
|
-
logger.info(`Starting backend-proxy-middleware using following configuration:\nbackend: ${JSON.stringify(
|
|
45
|
+
logger.info(`Starting backend-proxy-middleware using following configuration:\nbackend: ${JSON.stringify({
|
|
46
|
+
...backend,
|
|
47
|
+
proxy: formatProxyForLogging(backend.proxy)
|
|
48
|
+
})}\noptions: ${JSON.stringify(configOptions)}'`);
|
|
56
49
|
return (req, res, next) => {
|
|
57
50
|
if (req.path.startsWith(backend.path)) {
|
|
58
51
|
proxyFn(req, res, next);
|
|
@@ -67,5 +60,5 @@ module.exports = ({ options }) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
67
60
|
logger.error(message);
|
|
68
61
|
throw new Error(message);
|
|
69
62
|
}
|
|
70
|
-
}
|
|
63
|
+
};
|
|
71
64
|
//# sourceMappingURL=middleware.js.map
|
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.
|
|
12
|
+
"version": "0.8.1",
|
|
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": "20.6.1",
|
|
29
29
|
"prompts": "2.4.2",
|
|
30
30
|
"proxy-from-env": "1.1.0",
|
|
31
|
-
"@sap-ux/axios-extension": "1.
|
|
32
|
-
"@sap-ux/btp-utils": "0.
|
|
33
|
-
"@sap-ux/logger": "0.
|
|
34
|
-
"@sap-ux/store": "0.
|
|
31
|
+
"@sap-ux/axios-extension": "1.15.1",
|
|
32
|
+
"@sap-ux/btp-utils": "0.15.0",
|
|
33
|
+
"@sap-ux/logger": "0.6.0",
|
|
34
|
+
"@sap-ux/store": "0.7.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/express": "4.17.21",
|