Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove NGrok. Configure Tunnel URL #2461

Merged
merged 9 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v10.14.2
v16.13.2
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## v4.15.1 - 2024 - 09 - 12
## Update Tunnels
- [client/main] Remove NGrok dependency. Allow to paste the Tunnel URL in settings to enable remote bots.

## v4.14.1 - 2021 - 11 - 12
## Added
- [main] Bumped `electron` to v13.6.1 in PR [2318](https://github.com/microsoft/BotFramework-Emulator/pull/2318) (fixes electron bug caused by [Let's Encrypt root certificate expiration](https://github.com/electron/electron/issues/31212))
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
"overrides": {
"minimist@<1.2.6": ">=1.2.6",
"follow-redirects@<1.14.8": ">=1.14.8",
"serialize-javascript@<3.1.0": ">=3.1.0",
"serialize-javascript@<6.0.2": ">=6.0.2",
"postcss@<7.0.36": ">=7.0.36",
"trim-newlines@<3.0.1": ">=3.0.1",
"parse-path@<5.0.0": ">=5.0.0",
Expand Down
2 changes: 0 additions & 2 deletions packages/app/client/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,11 @@ export const CONTENT_TYPE_APP_SETTINGS = 'application/vnd.microsoft.bfemulator.d
export const CONTENT_TYPE_WELCOME_PAGE = 'application/vnd.microsoft.bfemulator.document.welcome';
export const CONTENT_TYPE_TRANSCRIPT = 'application/vnd.microsoft.bfemulator.document.transcript';
export const CONTENT_TYPE_LIVE_CHAT = SharedConstants.ContentTypes.CONTENT_TYPE_LIVE_CHAT;
export const CONTENT_TYPE_NGROK_DEBUGGER = SharedConstants.ContentTypes.CONTENT_TYPE_NGROK_DEBUGGER;

export const NAVBAR_BOT_EXPLORER = 'navbar.botExplorer';
export const NAVBAR_SETTINGS = 'navbar.settings';
export const NAVBAR_NOTIFICATIONS = 'navbar.notifications';
export const NAVBAR_RESOURCES = 'navbar.resources';
export const NAVBAR_NGROK_DEBUGGER = 'navbar.ngrokDebugger';

export const EDITOR_KEY_PRIMARY = 'primary';
export const EDITOR_KEY_SECONDARY = 'secondary';
Expand Down
1 change: 0 additions & 1 deletion packages/app/client/src/state/sagas/botSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ export class BotSagas {
})
);

// call emulator to report proper status to chat panel (listening / ngrok)
res = yield ConversationService.sendInitialLogReport(serverUrl, conversationId, action.payload.endpoint);
if (!res.ok) {
yield* throwErrorFromResponse('Error occurred while sending the initial log report', res);
Expand Down
4 changes: 0 additions & 4 deletions packages/app/client/src/state/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ import {
Settings,
ThemeState,
UpdateState,
ngrokTunnel,
NgrokTunnelState,
} from '@bfemulator/app-shared';

import { forwardToMain } from './middleware/forwardToMain';
Expand All @@ -98,7 +96,6 @@ export interface RootState {
settings?: Settings;
theme?: ThemeState;
update?: UpdateState;
ngrokTunnel?: NgrokTunnelState;
}

const DEFAULT_STATE = {};
Expand Down Expand Up @@ -137,7 +134,6 @@ function initStore(): Store<RootState> {
settings: settingsReducer,
theme,
update,
ngrokTunnel,
}),
DEFAULT_STATE,
storeEnhancer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import {
close as closeEditorDocument,
executeCommand,
framework,
ngrokTunnel,
saveFrameworkSettings,
setFrameworkSettings,
SharedConstants,
Expand Down Expand Up @@ -106,7 +105,7 @@ describe('The AppSettingsEditorContainer', () => {
});

beforeEach(() => {
mockStore = createStore(combineReducers({ framework, ngrokTunnel }));
mockStore = createStore(combineReducers({ framework }));
mockStore.dispatch(
setFrameworkSettings({
autoUpdate: true,
Expand All @@ -121,6 +120,8 @@ describe('The AppSettingsEditorContainer', () => {
use10Tokens: false,
useCodeValidation: false,
usePrereleases: false,
tunnelUrl: '',
localPort: 0,
})
);
mockDispatch = jest.spyOn(mockStore, 'dispatch');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,23 @@ import {
} from '@bfemulator/ui-react';
import * as React from 'react';
import { ChangeEvent } from 'react';
import { ipcRenderer } from 'electron';

import { GenericDocument } from '../../layout';
import { generateHash } from '../../../state/helpers/botHelpers';
import { TunnelCheckTimeInterval, TunnelStatus } from '../../../state/actions/ngrokTunnelActions';
import { NgrokStatusIndicator } from '../ngrokDebugger/ngrokStatusIndicator';

import * as styles from './appSettingsEditor.scss';

export interface AppSettingsEditorProps {
documentId?: string;
dirty?: boolean;
framework?: FrameworkSettings;
ngrokTunnelStatus?: TunnelStatus;
ngrokLastPingInterval?: TunnelCheckTimeInterval;

createAriaAlert?: (msg: string) => void;
discardChanges?: () => void;
onAnchorClick?: (url: string) => void;
openBrowseForNgrok: () => Promise<string>;
saveFrameworkSettings?: (framework: FrameworkSettings) => void;
setDirtyFlag?: (dirty: boolean) => void;
onOpenNgrokStatusViewerClick: () => void;
}

export interface AppSettingsEditorState extends Partial<FrameworkSettings> {
Expand All @@ -79,7 +74,6 @@ function shallowEqual(x: any, y: any) {

export class AppSettingsEditor extends React.Component<AppSettingsEditorProps, AppSettingsEditorState> {
public state = {} as AppSettingsEditorState;
private pathToNgrokInputRef: HTMLInputElement;

public static getDerivedStateFromProps(
newProps: AppSettingsEditorProps,
Expand All @@ -88,33 +82,28 @@ export class AppSettingsEditor extends React.Component<AppSettingsEditorProps, A
if (newProps.framework.hash === prevState.hash) {
return prevState;
}

return {
...newProps.framework,
dirty: newProps.dirty,
pendingUpdate: false,
};
}

public componentDidMount(): void {
if (this.pathToNgrokInputRef) {
this.pathToNgrokInputRef.focus();
}
public async componentDidMount(): Promise<void> {
this.setState({ localPort: await this.getLocalPort() });
}

public render(): JSX.Element {
const {
ngrokPath = '',
useCustomId = false,
bypassNgrokLocalhost = true,
runNgrokAtStartup = false,
localhost = '',
locale = '',
use10Tokens = false,
useCodeValidation = false,
userGUID = '',
autoUpdate = false,
usePrereleases = false,
collectUsageData = false,
tunnelUrl = '',
localPort = 321,
rido-min marked this conversation as resolved.
Show resolved Hide resolved
} = this.state;

const inputProps = {
Expand All @@ -124,85 +113,6 @@ export class AppSettingsEditor extends React.Component<AppSettingsEditorProps, A
return (
<GenericDocument className={styles.appSettingsEditor}>
<Row>
<Column className={styles.spacing}>
<div>
<span className={styles.legend}>Service</span>
<p>
<LinkButton linkRole={true} onClick={this.onNgrokDocsClick}>
ngrok
</LinkButton>{' '}
is network tunneling software. The Bot Framework Emulator works with ngrok to communicate with bots
hosted remotely. Read the{' '}
<LinkButton linkRole={true} onClick={this.onNgrokTunnelingDocsClick}>
wiki page
</LinkButton>{' '}
to learn more about using ngrok and how to download it.
</p>
<Row align={RowAlignment.Center} className={styles.marginBottomRow}>
<TextField
className={styles.appSettingsInput}
inputContainerClassName={styles.inputContainer}
inputRef={this.setNgrokInputRef}
readOnly={false}
value={ngrokPath}
onChange={this.onInputChange}
name="ngrokPath"
label={'Path to ngrok'}
/>
<PrimaryButton onClick={this.onClickBrowse} text="Browse" className={styles.browseButton} />
</Row>
<Checkbox
className={styles.checkboxOverrides}
checked={bypassNgrokLocalhost}
onChange={this.onChangeCheckBox}
id="ngrok-bypass"
aria-label="Bypass ngrok for local addresses, Service"
label="Bypass ngrok for local addresses"
name="bypassNgrokLocalhost"
/>
<Checkbox
className={styles.checkboxOverrides}
checked={runNgrokAtStartup}
onChange={this.onChangeCheckBox}
id="ngrok-startup"
aria-label="Run ngrok when the Emulator starts up, Service"
label="Run ngrok when the Emulator starts up"
name="runNgrokAtStartup"
/>
<Row align={RowAlignment.Center} className={styles.marginBottomRow}>
<TextField
className={styles.appSettingsInput}
inputContainerClassName={styles.inputContainer}
readOnly={false}
value={localhost}
onChange={this.onInputChange}
name="localhost"
label="localhost override"
/>
</Row>
<Row align={RowAlignment.Center}>
<TextField
className={styles.appSettingsInput}
inputContainerClassName={styles.inputContainer}
readOnly={false}
value={locale}
name="locale"
onChange={this.onInputChange}
label="Locale"
/>
</Row>
<div className={styles.tunnelStatus}>
<NgrokStatusIndicator
tunnelStatus={this.props.ngrokTunnelStatus}
timeIntervalSinceLastPing={this.props.ngrokLastPingInterval}
header="Tunnel Status"
/>
<LinkButton linkRole={true} onClick={this.props.onOpenNgrokStatusViewerClick}>
Click here to go to the Ngrok Status viewer
</LinkButton>
</div>
</div>
</Column>
<Column className={[styles.rightColumn, styles.spacing].join(' ')}>
<div>
<span className={styles.legend}>User settings</span>
Expand Down Expand Up @@ -270,6 +180,22 @@ export class AppSettingsEditor extends React.Component<AppSettingsEditorProps, A
name="usePrereleases"
/>
</div>
<div>
<span className={styles.legend}>Configure Tunnel</span>
<span>Configure a tunnel to port {localPort}: </span>
<b contentEditable="true">devtunnel host -a -p {localPort}</b>
<Row className={styles.marginBottomRow} align={RowAlignment.Top}>
<TextField
className={styles.appSettingsInput}
inputContainerClassName={styles.inputContainer}
readOnly={false}
value={tunnelUrl}
name="tunnelUrl"
onChange={this.onInputChange}
label="Tunnel Url"
/>
</Row>
</div>
<div>
<span className={styles.legend}>Data Collection</span>
<Checkbox
Expand Down Expand Up @@ -315,29 +241,13 @@ export class AppSettingsEditor extends React.Component<AppSettingsEditorProps, A
this.updateDirtyFlag(change);
};

private onClickBrowse = async (): Promise<void> => {
const ngrokPath = await this.props.openBrowseForNgrok();
if (ngrokPath === null) {
return; // Cancelled browse dialog
}
const change = { ngrokPath };
this.setState(change);
this.updateDirtyFlag(change);
};

private onInputChange = (event: ChangeEvent<HTMLInputElement>): void => {
const { value, name } = event.target;
const change = { [name]: value };
this.setState(change);
this.updateDirtyFlag(change);
};

private onNgrokDocsClick = this.createAnchorClickHandler('https://ngrok.com/');

private onNgrokTunnelingDocsClick = this.createAnchorClickHandler(
'https://github.com/Microsoft/BotFramework-Emulator/wiki/Tunneling-(ngrok)'
);

private onPrivacyStatementClick = this.createAnchorClickHandler('https://privacy.microsoft.com/privacystatement');

private onSaveClick = async () => {
Expand All @@ -350,9 +260,6 @@ export class AppSettingsEditor extends React.Component<AppSettingsEditorProps, A
this.setState({ dirty: false });
this.props.saveFrameworkSettings(newState);
this.props.createAriaAlert('App settings saved.');
if (this.pathToNgrokInputRef) {
this.pathToNgrokInputRef.focus();
}
};

private updateDirtyFlag(change: { [prop: string]: any }) {
Expand All @@ -361,7 +268,9 @@ export class AppSettingsEditor extends React.Component<AppSettingsEditorProps, A
this.props.setDirtyFlag(dirty);
}

private setNgrokInputRef = (ref: HTMLInputElement): void => {
this.pathToNgrokInputRef = ref;
private getLocalPort = async () => {
const lp = await ipcRenderer.invoke('local-server-port');
console.log('LOCAL PORT', lp);
rido-min marked this conversation as resolved.
Show resolved Hide resolved
return lp;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ import { AppSettingsEditor, AppSettingsEditorProps } from './appSettingsEditor';
const mapStateToProps = (state: RootState, ownProps: AppSettingsEditorProps) => ({
...ownProps,
framework: state.framework,
ngrokLastPingInterval: state.ngrokTunnel.timeIntervalSinceLastPing,
ngrokTunnelStatus: state.ngrokTunnel.tunnelStatus,
});

const mapDispatchToProps = (dispatch: (action: Action) => void, ownProps: AppSettingsEditorProps) => ({
Expand All @@ -66,18 +64,6 @@ const mapDispatchToProps = (dispatch: (action: Action) => void, ownProps: AppSet
onAnchorClick: (url: string) => {
dispatch(executeCommand(true, SharedConstants.Commands.Electron.OpenExternal, null, url));
},
openBrowseForNgrok: async () => {
const dialogOptions = {
title: 'Browse for ngrok',
buttonLabel: 'Select ngrok',
properties: ['openFile'],
};
return new Promise(resolve => {
dispatch(executeCommand(true, SharedConstants.Commands.Electron.ShowOpenDialog, resolve, dialogOptions));
});
},
onOpenNgrokStatusViewerClick: () =>
dispatch(executeCommand(true, SharedConstants.Commands.Ngrok.OpenStatusViewer, null)),
saveFrameworkSettings: (framework: FrameworkSettings) => dispatch(saveFrameworkSettings(framework)),
setDirtyFlag: debounce((dirty: boolean) => dispatch(setDirtyFlag(ownProps.documentId, dirty)), 300),
});
Expand Down
5 changes: 1 addition & 4 deletions packages/app/client/src/ui/editor/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { Document } from '../../state/reducers/editor';

import { MarkdownPage } from './markdownPage/markdownPage';

import { AppSettingsEditorContainer, EmulatorContainer, WelcomePageContainer, NgrokDebuggerContainer } from './index';
import { AppSettingsEditorContainer, EmulatorContainer, WelcomePageContainer } from './index';

interface EditorFactoryProps {
document?: Document;
Expand Down Expand Up @@ -77,9 +77,6 @@ export class EditorFactory extends React.Component<EditorFactoryProps> {
/>
);

case SharedConstants.ContentTypes.CONTENT_TYPE_NGROK_DEBUGGER:
return <NgrokDebuggerContainer documentId={document.documentId} dirty={this.props.document.dirty} />;

default:
return false;
}
Expand Down
Loading
Loading