import * as React from 'react'; import { sprintf } from 'sprintf-js'; import styled from 'styled-components'; import { IpVersion } 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 { BackBarItem, NavigationBar, NavigationContainer, NavigationItems, NavigationScrollbars, TitleBarItem, } from './NavigationBar'; import Selector, { ISelectorItem } from './cell/Selector'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; const MIN_WIREGUARD_MTU_VALUE = 1280; const MAX_WIREGUARD_MTU_VALUE = 1420; const WIREUGARD_UDP_PORTS = [51820, 53]; type OptionalPort = number | undefined; type OptionalIpVersion = IpVersion | 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 StyledSelectorForFooter = (styled(Selector)({ marginBottom: 0, }) as unknown) as new () => Selector; export const StyledInputFrame = styled(Cell.InputFrame)({ flex: 0, }); interface IProps { wireguard: { port?: number; ipVersion?: IpVersion }; wireguardMtu?: number; setWireguardMtu: (value: number | undefined) => void; setWireguardRelayPortAndIpVersion: (port?: number, ipVersion?: IpVersion) => void; onViewWireguardKeys: () => void; onClose: () => void; } export default class WireguardSettings extends React.Component { private wireguardPortItems: Array>; private wireguardIpVersionItems: Array>; constructor(props: IProps) { super(props); const automaticPort: ISelectorItem = { label: messages.gettext('Automatic'), value: undefined, }; this.wireguardPortItems = [automaticPort].concat( WIREUGARD_UDP_PORTS.map(mapPortToSelectorItem), ); this.wireguardIpVersionItems = [ { label: messages.gettext('Automatic'), value: undefined, }, { label: messages.gettext('IPv4'), value: 'ipv4', }, { label: messages.gettext('IPv6'), value: 'ipv6', }, ]; } public render() { return ( { // TRANSLATORS: Back button in navigation bar messages.pgettext('navigation-bar', 'Advanced') } { // TRANSLATORS: Title label in navigation bar messages.pgettext('wireguard-settings-nav', 'WireGuard settings') } {messages.pgettext('wireguard-settings-view', 'WireGuard settings')} { // TRANSLATORS: The hint displayed below the WireGuard port selector. messages.pgettext( 'wireguard-settings-view', 'The automatic setting will randomly choose from a wide range of ports.', ) } { // TRANSLATORS: The hint displayed below the WireGuard IP version selector. messages.pgettext( 'wireguard-settings-view', 'This allows access to WireGuard for devices that only support IPv6.', ) } {messages.pgettext('wireguard-settings-view', 'WireGuard key')} {messages.pgettext('wireguard-settings-view', 'MTU')} {sprintf( // TRANSLATORS: The hint displayed below the WireGuard MTU input field. // TRANSLATORS: Available placeholders: // TRANSLATORS: %(max)d - the maximum possible wireguard mtu value // TRANSLATORS: %(min)d - the minimum possible wireguard mtu value messages.pgettext( 'wireguard-settings-view', 'Set WireGuard MTU value. Valid range: %(min)d - %(max)d.', ), { min: MIN_WIREGUARD_MTU_VALUE, max: MAX_WIREGUARD_MTU_VALUE, }, )} ); } private onSelectWireguardPort = (port?: number) => { this.props.setWireguardRelayPortAndIpVersion(port, this.props.wireguard.ipVersion); }; private onSelectWireguardIpVersion = (ipVersion?: IpVersion) => { this.props.setWireguardRelayPortAndIpVersion(this.props.wireguard.port, ipVersion); }; private static removeNonNumericCharacters(value: string) { return value.replace(/[^0-9]/g, ''); } private onWireguardMtuSubmit = (value: string) => { const parsedValue = value === '' ? undefined : parseInt(value, 10); if (WireguardSettings.wireguarMtuIsValid(value)) { this.props.setWireguardMtu(parsedValue); } }; private static wireguarMtuIsValid(mtu: string): boolean { const parsedMtu = mtu ? parseInt(mtu) : undefined; return ( parsedMtu === undefined || (parsedMtu >= MIN_WIREGUARD_MTU_VALUE && parsedMtu <= MAX_WIREGUARD_MTU_VALUE) ); } }