diff --git a/package-lock.json b/package-lock.json index fe17c046a1..9c6cb473e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9437,8 +9437,7 @@ "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "es6-promisify": { "version": "5.0.0", @@ -9720,6 +9719,31 @@ } } }, + "express-http-proxy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/express-http-proxy/-/express-http-proxy-1.6.0.tgz", + "integrity": "sha512-7Re6Lepg96NA2wiv7DC5csChAScn4K76/UgYnC71XiITCT1cgGTJUGK6GS0pIixudg3Fbx3Q6mmEW3mZv5tHFQ==", + "requires": { + "debug": "^3.0.1", + "es6-promise": "^4.1.1", + "raw-body": "^2.3.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "express-robots-txt": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/express-robots-txt/-/express-robots-txt-0.4.1.tgz", diff --git a/package.json b/package.json index d8d0c72ab4..ecbbc07c95 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "conventional-changelog-cli": "^2.0.21", "core-js": "^2.6.9", "express": "^4.17.1", + "express-http-proxy": "^1.6.0", "express-robots-txt": "0.4.1", "lodash-es": "^4.17.15", "morgan": "^1.9.1", diff --git a/server.ts b/server.ts index 9a45732c99..69fda3072c 100644 --- a/server.ts +++ b/server.ts @@ -22,6 +22,14 @@ import * as express from 'express'; import { join } from 'path'; import * as robots from 'express-robots-txt'; import * as fs from 'fs'; +import * as proxy from 'express-http-proxy'; + +// * NOTE :: leave this as require() since this file is built Dynamically from webpack +const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = require('./dist/server/main'); + +// tslint:disable-next-line: ban-specific-imports +import { Environment } from 'src/environments/environment.model'; +const environment: Environment = require('./dist/server/main').environment; const logging = !!process.env.LOGGING; @@ -31,8 +39,19 @@ const app = express(); const PORT = process.env.PORT || 4200; const DIST_FOLDER = join(process.cwd(), 'dist'); -// * NOTE :: leave this as require() since this file is built Dynamically from webpack -const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = require('./dist/server/main'); +const ICM_BASE_URL = process.env.ICM_BASE_URL || environment.icmBaseURL; +if (!ICM_BASE_URL) { + console.error('ICM_BASE_URL not set'); + process.exit(1); +} + +if (process.env.TRUST_ICM) { + // trust https certificate if self-signed + // see also https://medium.com/nodejs-tips/ssl-certificate-explained-fc86f8aa43d4 + // and https://github.com/angular/universal/issues/856#issuecomment-436364729 + process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + console.warn("ignoring all TLS verification as 'TRUST_ICM' variable is set - never use this in production!"); +} // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) app.engine( @@ -95,6 +114,26 @@ app.get( }) ); +const icmProxy = proxy(ICM_BASE_URL, { + // preserve original path + proxyReqPathResolver: req => req.originalUrl, + proxyReqOptDecorator: options => { + if (process.env.TRUST_ICM) { + // https://github.com/villadora/express-http-proxy#q-how-to-ignore-self-signed-certificates- + options.rejectUnauthorized = false; + } + return options; + }, + // fool ICM so it thinks it's running here + // https://www.npmjs.com/package/express-http-proxy#preservehosthdr + preserveHostHdr: true, +}); + +if (process.env.PROXY_ICM) { + console.log("making ICM available for all requests to '/INTERSHOP'"); + app.use('/INTERSHOP', icmProxy); +} + // All regular routes use the Universal engine app.get('*', (req: express.Request, res: express.Response) => { if (logging) { @@ -107,7 +146,15 @@ app.get('*', (req: express.Request, res: express.Response) => { res, }, (err: Error, html: string) => { - res.status(html ? res.statusCode : 500).send(html || err.message); + if (html) { + let newHtml: string; + if (process.env.PROXY_ICM && req.get('host')) { + newHtml = html.replace(new RegExp(ICM_BASE_URL, 'g'), `${req.protocol}://${req.get('host')}`); + } + res.status(res.statusCode).send(newHtml || html); + } else { + res.status(500).send(err.message); + } if (logging) { console.log(`RES ${res.statusCode} ${req.url}`); if (err) { diff --git a/src/main.server.ts b/src/main.server.ts index 33ed185061..5e372d497c 100644 --- a/src/main.server.ts +++ b/src/main.server.ts @@ -9,3 +9,4 @@ if (environment.production) { export { AppServerModule } from './app/app.server.module'; export { ngExpressEngine } from '@nguniversal/express-engine'; export { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; +export { environment } from './environments/environment';