import * as React from 'react'; import { sprintf } from 'sprintf-js'; import styled from 'styled-components'; import { BridgeState, RelayProtocol } from '../../shared/daemon-rpc-types'; import { messages } from '../../shared/gettext'; import { AriaDescription, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup'; import * as Cell from './cell'; import { Layout, SettingsContainer } from './Layout'; import { ModalContainer } from './Modal'; import { BackBarItem, NavigationBar, NavigationContainer, NavigationItems, NavigationScrollbars, TitleBarItem, } from './NavigationBar'; import Selector, { ISelectorItem } from './cell/Selector'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; const MIN_MSSFIX_VALUE = 1000; const MAX_MSSFIX_VALUE = 1450; const UDP_PORTS = [1194, 1195, 1196, 1197, 1300, 1301, 1302]; const TCP_PORTS = [80, 443]; type OptionalPort = number | undefined; type OptionalRelayProtocol = RelayProtocol | undefined; function mapPortToSelectorItem(value: number): ISelectorItem { return { label: value.toString(), value }; } export const StyledNavigationScrollbars = styled(NavigationScrollbars)({ flex: 1, }); export const StyledSelectorContainer = styled.div({ flex: 0, }); export const StyledInputFrame = styled(Cell.InputFrame)({ flex: 0, }); interface IProps { openvpn: { protocol?: RelayProtocol; port?: number; }; mssfix?: number; bridgeState: BridgeState; setOpenVpnMssfix: (value: number | undefined) => void; setOpenVpnRelayProtocolAndPort: (protocol?: RelayProtocol, port?: number) => void; setBridgeState: (value: BridgeState) => void; onClose: () => void; } export default class OpenVpnSettings extends React.Component { private portItems: { [key in RelayProtocol]: Array> }; private protocolItems: Array>; private bridgeStateItems: Array>; constructor(props: IProps) { super(props); const automaticPort: ISelectorItem = { label: messages.gettext('Automatic'), value: undefined, }; this.portItems = { udp: [automaticPort].concat(UDP_PORTS.map(mapPortToSelectorItem)), tcp: [automaticPort].concat(TCP_PORTS.map(mapPortToSelectorItem)), }; this.protocolItems = [ { label: messages.gettext('Automatic'), value: undefined, }, { label: messages.gettext('TCP'), value: 'tcp', }, { label: messages.gettext('UDP'), value: 'udp', }, ]; this.bridgeStateItems = [ { label: messages.gettext('Automatic'), value: 'auto', }, { label: messages.gettext('On'), value: 'on', }, { label: messages.gettext('Off'), value: 'off', }, ]; } public render() { return ( { // TRANSLATORS: Back button in navigation bar messages.pgettext('navigation-bar', 'Advanced') } { // TRANSLATORS: Title label in navigation bar messages.pgettext('openvpn-settings-nav', 'OpenVPN settings') } {messages.pgettext('openvpn-settings-view', 'OpenVPN settings')} {this.props.openvpn.protocol ? ( ) : undefined} {messages.pgettext('openvpn-settings-view', 'Mssfix')} {sprintf( // TRANSLATORS: The hint displayed below the Mssfix input field. // TRANSLATORS: Available placeholders: // TRANSLATORS: %(max)d - the maximum possible mssfix value // TRANSLATORS: %(min)d - the minimum possible mssfix value messages.pgettext( 'openvpn-settings-view', 'Set OpenVPN MSS value. Valid range: %(min)d - %(max)d.', ), { min: MIN_MSSFIX_VALUE, max: MAX_MSSFIX_VALUE, }, )} ); } private onSelectOpenvpnProtocol = (protocol?: RelayProtocol) => { this.props.setOpenVpnRelayProtocolAndPort(protocol); }; private onSelectOpenVpnPort = (port?: number) => { this.props.setOpenVpnRelayProtocolAndPort(this.props.openvpn.protocol, port); }; private onSelectBridgeState = (bridgeState: BridgeState) => { this.props.setBridgeState(bridgeState); }; private onMssfixSubmit = (value: string) => { const parsedValue = value === '' ? undefined : parseInt(value, 10); if (OpenVpnSettings.mssfixIsValid(value)) { this.props.setOpenVpnMssfix(parsedValue); } }; private static removeNonNumericCharacters(value: string) { return value.replace(/[^0-9]/g, ''); } private static mssfixIsValid(mssfix: string): boolean { const parsedMssFix = mssfix ? parseInt(mssfix) : undefined; return ( parsedMssFix === undefined || (parsedMssFix >= MIN_MSSFIX_VALUE && parsedMssFix <= MAX_MSSFIX_VALUE) ); } }