Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { WebChatHeader } from './WebChatHeader';
import { WebChatComposer } from './WebChatComposer';
import { BotSecret, ChatData, RestartOption } from './types';

const BASEPATH = process.env.PUBLIC_URL || 'http://localhost:3000/';
const BASEPATH = process.env.PUBLIC_URL || `http://${location.hostname}:3000/`;
// TODO: Refactor to include Webchat header component as a part of WebchatComposer to avoid this variable.
const webChatHeaderHeight = '85px';

Expand Down Expand Up @@ -67,7 +67,7 @@ export const WebChatPanel: React.FC<WebChatPanelProps> = ({
const conversationServerPort = await conversationService.setUpConversationServer();
try {
// set up Web Chat traffic listener
webChatTrafficChannel.current = new WebSocket(`ws://localhost:${conversationServerPort}/ws/traffic`);
webChatTrafficChannel.current = new WebSocket(`ws://${location.hostname}:${conversationServerPort}/ws/traffic`);
if (webChatTrafficChannel.current) {
webChatTrafficChannel.current.onmessage = (event) => {
const data:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class ConversationService {
secret,
domain: `${this.directlineHostUrl}/v3/directline`,
webSocket: true,
streamUrl: `ws://localhost:${this.restServerForWSPort}/ws/conversation/${conversationId}`,
streamUrl: `ws://${location.hostname}:${this.restServerForWSPort}/ws/conversation/${conversationId}`,
});
return directLine;
}
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/client/src/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ export const defaultTeamsManifest: TeamsManifest = {
};

export const defaultBotPort = 3979;
export const defaultBotEndpoint = `http://localhost:${defaultBotPort}/api/messages`;
export const defaultBotEndpoint = `http://${location.hostname}:${defaultBotPort}/api/messages`;

const DAYS_IN_MS = 1000 * 60 * 60 * 24;
export const SURVEY_PARAMETERS = {
Expand Down
5 changes: 3 additions & 2 deletions Composer/packages/electron-server/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ const waitForMainWindowToShow = new Promise((resolve) => {

// webpack dev server runs on :3000
const getBaseUrl = () => {
const host = process.env.COMPOSER_HOST ?? 'localhost';
if (isDevelopment) {
return 'http://localhost:3000/';
return `http://${host}:3000/`;
}
if (!serverPort) {
throw new Error('getBaseUrl() called before serverPort is defined.');
}
return `http://localhost:${serverPort}/`;
return `http://${host}:${serverPort}/`;
};

// set production flag
Expand Down
3 changes: 2 additions & 1 deletion Composer/packages/server/src/controllers/publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import AssetService from '../services/asset';
import logger from '../logger';
import { LocationRef } from '../models/bot/interface';
import { TelemetryService } from '../services/telemetry';
import { serverListenHost, serverHostname } from '../settings/env';

const log = logger.extend('publisher-controller');

Expand Down Expand Up @@ -318,7 +319,7 @@ export const PublishController = {
const pluginMethod = ExtensionContext.extensions.publish[extensionName].methods.setupRuntimeLogServer;
if (typeof pluginMethod === 'function') {
try {
const runtimeLogUrl = await pluginMethod.call(null, projectId);
const runtimeLogUrl = await pluginMethod.call(null, projectId, serverHostname, serverListenHost);
return res.status(200).send(runtimeLogUrl);
} catch (ex) {
res.status(400).json({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { serverHostname } from '../../settings/env';

import { BotEndpoint } from './entities/botEndpoint';
import { Attachments } from './entities/attachments';
import { ConversationSet } from './entities/conversationSet';
Expand All @@ -27,7 +29,7 @@ class DLServerContext {
conversations: new ConversationSet(),
endpoints: new EndpointSet(),
attachments: new Attachments(),
serviceUrl: serverPort ? `http://localhost:${serverPort}` : '',
serviceUrl: serverPort ? `http://${serverHostname}:${serverPort}` : '',
dispatchers: {
getDefaultEndpoint: this.getDefaultEndpoint,
updateConversation: this.updateConversation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
ConversationNetworkTrafficItem,
} from '@botframework-composer/types';

import { serverListenHost } from '../../settings/env';

import log from './logger';

const socketTrafficChannelKey = 'DL_TRAFFIC_SOCKET';
Expand Down Expand Up @@ -87,7 +89,7 @@ export class WebSocketServer {
});
this.port = port;
log(`Using ${port} port for directline`);
this.restServer.listen(port);
this.restServer.listen(port, serverListenHost);

app.use('/ws/conversation/:conversationId', (req: express.Request, res: express.Response) => {
if (!(req as any).claimUpgrade) {
Expand Down
9 changes: 6 additions & 3 deletions Composer/packages/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { mountDirectLineRoutes } from './directline/mountDirectlineRoutes';
import { mountAttachmentRoutes } from './directline/mountAttachmentRoutes';
import { cleanHostedBots } from './utility/cleanHostedBots';
import { getVersion } from './utility/getVersion';
import { serverListenHost, serverHostname } from './settings/env';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const session = require('express-session');
Expand Down Expand Up @@ -183,12 +184,14 @@ export async function start(electronContext?: ElectronContext): Promise<number |
});

let server;
await new Promise((resolve) => {
server = app.listen(port, () => {
await new Promise<void>((resolve) => {
server = app.listen(port, serverListenHost, () => {
if (process.env.NODE_ENV === 'production') {
// We don't use the debug logger here because we always want it to be shown.
// eslint-disable-next-line no-console
console.log(`\n\n${chalk.green('Composer now running at:')}\n\n${chalk.blue(`http://localhost:${port}`)}\n`);
console.log(
`\n\n${chalk.green('Composer now running at:')}\n\n${chalk.blue(`http://${serverHostname}:${port}`)}\n`
);
}
resolve();
});
Expand Down
5 changes: 4 additions & 1 deletion Composer/packages/server/src/settings/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import childProcess from 'child_process';

import { Path } from '../utility/path';

export const serverListenHost = process.env.COMPOSER_HOST || 'localhost';
export const serverHostname = serverListenHost === '0.0.0.0' || !serverListenHost ? 'localhost' : serverListenHost;

export const absHosted = process.env.COMPOSER_AUTH_PROVIDER === 'abs-h';
export const absHostRoot = process.env.WEBSITE_HOSTNAME
? `https://${process.env.WEBSITE_HOSTNAME}`
: 'http://localhost:3978';
: `http://${serverHostname}:3978`;

let folder = process.env.COMPOSER_BOTS_FOLDER;
if (folder?.endsWith(':')) {
Expand Down
10 changes: 7 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
# before doing yarn install due to yarn workspace symlinking.
#
################
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-focal as base
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-focal as base
RUN apt update \
&& apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates \
&& curl -sL https://deb.nodesource.com/setup_14.x | bash - \
&& apt install -y nodejs libgomp1 \
&& npm install -g yarn
&& corepack enable \
&& corepack prepare yarn@3.2.1 --activate \
&& yarn --version

FROM base as build
ARG YARN_ARGS
Expand All @@ -32,6 +34,7 @@ RUN yarn build:prod $YARN_ARGS
ENV COMPOSER_REMOTE_EXTENSIONS_DIR "/src/remote-extensions"
ENV COMPOSER_REMOTE_EXTENSION_DATA_DIR "/src/extension-data"
ENV COMPOSER_EXTENSION_MANIFEST "/src/extensions.json"
ENV COMPOSER_HOST="0.0.0.0"
CMD ["yarn","start:server"]

FROM base as composerbasic
Expand All @@ -46,7 +49,7 @@ COPY --from=build /src/Composer/packages ./packages
COPY --from=build /src/extensions ../extensions

ENV NODE_ENV "production"
RUN yarn --production --immutable --force $YARN_ARGS && yarn cache clean
RUN yarn install --immutable $YARN_ARGS && yarn cache clean

FROM base
ENV NODE_ENV "production"
Expand All @@ -59,4 +62,5 @@ ENV COMPOSER_BUILTIN_EXTENSIONS_DIR "/app/extensions"
ENV COMPOSER_REMOTE_EXTENSIONS_DIR "/app/remote-extensions"
ENV COMPOSER_REMOTE_EXTENSION_DATA_DIR "/app/extension-data"
ENV COMPOSER_EXTENSION_MANIFEST "/app/extensions.json"
ENV COMPOSER_HOST="0.0.0.0"
CMD ["yarn","start:server"]
4 changes: 3 additions & 1 deletion extensions/localPublish/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,11 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
}
};

setupRuntimeLogServer = async (projectId: string) => {
setupRuntimeLogServer = async (projectId: string, serverHostname?: string, serverListenHost?: string) => {
await RuntimeLogServer.init({
log: this.composer.log,
hostname: serverHostname,
boundHost: serverListenHost,
});
return RuntimeLogServer.getRuntimeLogStreamingUrl(projectId);
};
Expand Down
16 changes: 13 additions & 3 deletions extensions/localPublish/src/runtimeLogServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ export class RuntimeLogServer {
private static servers: WSServer = {};
private static sockets: Record<string, WebSocket> = {};
private static port: number;
private static hostname: string;

public static getRuntimeLogStreamingUrl(projectId: string): string {
return `ws://localhost:${this.port}/ws/runtimeLog/${projectId}`;
return `ws://${this.hostname}:${this.port}/ws/runtimeLog/${projectId}`;
}

public static async init({ log }: { log: Debugger }): Promise<number | void> {
public static async init({
log,
boundHost = 'localhost',
hostname = 'localhost',
}: {
log: Debugger;
boundHost?: string;
hostname?: string;
}): Promise<number | void> {
if (!this.restServer) {
const app = express();
this.restServer = http.createServer(app);
Expand All @@ -42,7 +51,7 @@ export class RuntimeLogServer {
return preferredPort;
});
log(`Using ${port} port for runtime-log`);
this.restServer.listen(port);
this.restServer.listen(port, boundHost);

app.use('/ws/runtimeLog/:projectId', (req: Request, res: Response) => {
if (!(req as any).claimUpgrade) {
Expand Down Expand Up @@ -74,6 +83,7 @@ export class RuntimeLogServer {
}
});
this.port = port;
this.hostname = hostname;
return this.port;
}
}
Expand Down