import log from 'electron-log'; import moment from 'moment'; import * as React from 'react'; import { Component, Text, View } from 'reactxp'; import { sprintf } from 'sprintf-js'; import { messages } from '../../shared/gettext'; import { IWgKey, WgKeyState } from '../redux/settings/reducers'; import * as AppButton from './AppButton'; import ClipboardLabel from './ClipboardLabel'; import ImageView from './ImageView'; import { Container, Layout } from './Layout'; import { BackBarItem, NavigationBar, NavigationContainer, NavigationItems } from './NavigationBar'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; import styles from './WireguardKeysStyles'; export interface IProps { keyState: WgKeyState; isOffline: boolean; locale: string; onClose: () => void; onGenerateKey: () => void; onReplaceKey: (old: IWgKey) => void; onVerifyKey: (publicKey: IWgKey) => void; onVisitWebsiteKey: () => Promise; } export default class WireguardKeys extends Component { public render() { return ( {// TRANSLATORS: Back button in navigation bar messages.pgettext('wireguard-keys-nav', 'Advanced')} {messages.pgettext('wireguard-keys-nav', 'WireGuard key')} {messages.pgettext('wireguard-keys', 'Public key')} {this.getKeyText()} {messages.pgettext('wireguard-keys', 'Key generated')} {this.ageOfKeyString()} {this.props.isOffline ? ( {messages.pgettext( 'wireguard-key-view', 'Unable to manage keys while in a blocked state', )} ) : ( {this.keyValidityLabel()} )} {this.getGenerateButton()} {messages.pgettext('wireguard-key-view', 'Verify key')} {messages.pgettext('wireguard-key-view', 'Manage keys')} ); } private isVerifyButtonDisabled(): boolean { switch (this.props.keyState.type) { case 'key-set': return false || this.props.isOffline; default: return true; } } private getOnVerifyKeyCb() { return () => { switch (this.props.keyState.type) { case 'key-set': const key = this.props.keyState.key; this.props.onVerifyKey(key); break; default: log.error(`onVerifyKey called from invalid state - ${this.props.keyState.type}`); } }; } /// Action button can either generate or verify a key private getGenerateButton() { const generateText = messages.pgettext('wireguard-key-view', 'Generate key'); const regenerateText = messages.pgettext('wireguard-key-view', 'Regenerate key'); let buttonText = generateText; let generateKey = this.props.onGenerateKey; switch (this.props.keyState.type) { case 'key-set': buttonText = regenerateText; const key = this.props.keyState.key; generateKey = () => this.props.onReplaceKey(key); break; case 'being-verified': return this.busyButton(regenerateText); case 'being-replaced': case 'being-generated': return this.busyButton(messages.pgettext('wireguard-key-view', 'Generating key')); } return ( {buttonText} ); } private busyButton(message: string) { return ( {message} ); } private getKeyText() { switch (this.props.keyState.type) { case 'being-verified': case 'key-set': // mimicking the truncating of the key from website const publicKey = this.props.keyState.key.publicKey; return ( ); case 'being-replaced': case 'being-generated': return ; case 'too-many-keys': case 'generation-failure': return ( {this.formatKeygenFailure(this.props.keyState.type)} ); default: return ( {messages.pgettext('wireguard-key-view', 'No key set')} ); } } private keyValidityLabel() { switch (this.props.keyState.type) { case 'being-verified': return ; case 'key-set': const key = this.props.keyState.key; if (key.valid === true) { return ( {messages.pgettext('account-view', 'Key is valid')} ); } else if (key.valid === false) { return ( {messages.pgettext('wireguard-key-view', 'Key is invalid')} ); } else if (key.replacementFailure) { let failure = ''; switch (key.replacementFailure) { case 'too_many_keys': failure = this.formatKeygenFailure('too-many-keys'); break; case 'generation_failure': failure = this.formatKeygenFailure('generation-failure'); break; } const failureMessage = sprintf( messages.pgettext('wireguard-key-view', 'Failed to replace key - %(failure)s'), { failure }, ); return {failureMessage}; } else if (key.verificationFailed) { return ( {messages.pgettext('wireguard-key-view', 'Key verification failed')} ); } default: return null; } } private ageOfKeyString(): string { let keyCreatedSince = '-'; switch (this.props.keyState.type) { case 'key-set': case 'being-verified': keyCreatedSince = moment(this.props.keyState.key.created) .locale(this.props.locale) .fromNow(); break; } return keyCreatedSince; } private formatKeygenFailure(failure: 'too-many-keys' | 'generation-failure'): string { switch (failure) { case 'too-many-keys': return messages.pgettext('wireguard-key-view', 'Account has too many keys already'); case 'generation-failure': return messages.pgettext('wireguard-key-view', 'Failed to generate a key'); default: return failure; } } }