From ecc3d03ad5b9b7a1336a085bcd7526c50374c741 Mon Sep 17 00:00:00 2001 From: Colum Ferry Date: Mon, 12 Aug 2024 14:03:33 +0100 Subject: [PATCH] fix(module-federation): remote proxies should use https when host is configured with ssl #27360 --- .../lib/normalize-options.ts | 4 +++ .../module-federation-dev-server.impl.ts | 11 ++++++- .../module-federation-dev-server.impl.ts | 11 ++++++- .../module-federation/start-remote-proxies.ts | 31 ++++++++++++++++--- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/packages/angular/src/executors/module-federation-dev-server/lib/normalize-options.ts b/packages/angular/src/executors/module-federation-dev-server/lib/normalize-options.ts index bb30d2032c0381..19f46c1ab02a4a 100644 --- a/packages/angular/src/executors/module-federation-dev-server/lib/normalize-options.ts +++ b/packages/angular/src/executors/module-federation-dev-server/lib/normalize-options.ts @@ -4,6 +4,8 @@ import type { SchemaWithBrowserTarget, SchemaWithBuildTarget, } from '../schema'; +import { join } from 'path'; +import { workspaceRoot } from '@nx/devkit'; export function normalizeOptions(schema: Schema): NormalizedSchema { let buildTarget = (schema as SchemaWithBuildTarget).buildTarget; @@ -24,5 +26,7 @@ export function normalizeOptions(schema: Schema): NormalizedSchema { liveReload: schema.liveReload ?? true, open: schema.open ?? false, ssl: schema.ssl ?? false, + sslCert: schema.sslCert ? join(workspaceRoot, schema.sslCert) : undefined, + sslKey: schema.sslKey ? join(workspaceRoot, schema.sslKey) : undefined, }; } diff --git a/packages/angular/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts b/packages/angular/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts index 78f34f06e30d9f..fc031d03c202e4 100644 --- a/packages/angular/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts +++ b/packages/angular/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts @@ -156,7 +156,16 @@ export async function* moduleFederationDevServerExecutor( options ); - startRemoteProxies(staticRemotesConfig, mappedLocationsOfStaticRemotes); + startRemoteProxies( + staticRemotesConfig, + mappedLocationsOfStaticRemotes, + options.ssl + ? { + pathToCert: options.sslCert, + pathToKey: options.sslKey, + } + : undefined + ); const removeBaseUrlEmission = (iter: AsyncIterable) => mapAsyncIterable(iter, (v) => ({ diff --git a/packages/react/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts b/packages/react/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts index 60b8d386fc8802..c3920f557d0118 100644 --- a/packages/react/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts +++ b/packages/react/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts @@ -365,7 +365,16 @@ export default async function* moduleFederationDevServer( options ); - startRemoteProxies(staticRemotesConfig, mappedLocationsOfStaticRemotes); + startRemoteProxies( + staticRemotesConfig, + mappedLocationsOfStaticRemotes, + options.ssl + ? { + pathToCert: join(workspaceRoot, options.sslCert), + pathToKey: join(workspaceRoot, options.sslKey), + } + : undefined + ); return yield* combineAsyncIterables( currIter, diff --git a/packages/webpack/src/utils/module-federation/start-remote-proxies.ts b/packages/webpack/src/utils/module-federation/start-remote-proxies.ts index b3f004d4b4235d..352c1749a0304e 100644 --- a/packages/webpack/src/utils/module-federation/start-remote-proxies.ts +++ b/packages/webpack/src/utils/module-federation/start-remote-proxies.ts @@ -1,13 +1,33 @@ import type { Express } from 'express'; -import { logger } from '@nx/devkit'; +import { logger, ProjectGraph } from '@nx/devkit'; import { StaticRemotesConfig } from './parse-static-remotes-config'; +import { existsSync, readFileSync } from 'fs'; export function startRemoteProxies( staticRemotesConfig: StaticRemotesConfig, - mappedLocationsOfRemotes: Record + mappedLocationsOfRemotes: Record, + sslOptions?: { pathToCert: string; pathToKey: string } ) { const { createProxyMiddleware } = require('http-proxy-middleware'); const express = require('express'); + let sslCert: Buffer; + let sslKey: Buffer; + if (sslOptions && sslOptions.pathToCert && sslOptions.pathToKey) { + if (existsSync(sslOptions.pathToCert) && existsSync(sslOptions.pathToKey)) { + sslCert = readFileSync(sslOptions.pathToCert); + sslKey = readFileSync(sslOptions.pathToKey); + } else { + logger.warn( + `Encountered SSL options in project.json, however, the certificate files do not exist in the filesystem. Using http.` + ); + logger.warn( + `Attempted to find '${sslOptions.pathToCert}' and '${sslOptions.pathToKey}'.` + ); + } + } + const http = require('http'); + const https = require('https'); + logger.info(`NX Starting static remotes proxies...`); for (const app of staticRemotesConfig.remotes) { const expressProxy: Express = express(); @@ -15,11 +35,12 @@ export function startRemoteProxies( createProxyMiddleware({ target: mappedLocationsOfRemotes[app], changeOrigin: true, + secure: sslCert ? false : undefined, }) ); - const proxyServer = expressProxy.listen( - staticRemotesConfig.config[app].port - ); + const proxyServer = (sslCert ? https : http) + .createServer({ cert: sslCert, key: sslKey }, expressProxy) + .listen(staticRemotesConfig.config[app].port); process.on('SIGTERM', () => proxyServer.close()); process.on('exit', () => proxyServer.close()); }