parent
e62c687d93
commit
ebb0aab2f5
@ -1,8 +0,0 @@
|
|||||||
import { useSelector } from 'react-redux';
|
|
||||||
import AppState from 'App/State/AppState';
|
|
||||||
|
|
||||||
function useIsWindows() {
|
|
||||||
return useSelector((state: AppState) => state.system.status.item.isWindows);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useIsWindows;
|
|
@ -1,222 +0,0 @@
|
|||||||
import _ from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import Alert from 'Components/Alert';
|
|
||||||
import Form from 'Components/Form/Form';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
|
||||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
|
||||||
import PageContent from 'Components/Page/PageContent';
|
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
|
||||||
import { kinds } from 'Helpers/Props';
|
|
||||||
import SettingsToolbar from 'Settings/SettingsToolbar';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import AnalyticSettings from './AnalyticSettings';
|
|
||||||
import BackupSettings from './BackupSettings';
|
|
||||||
import HostSettings from './HostSettings';
|
|
||||||
import LoggingSettings from './LoggingSettings';
|
|
||||||
import ProxySettings from './ProxySettings';
|
|
||||||
import SecuritySettings from './SecuritySettings';
|
|
||||||
import UpdateSettings from './UpdateSettings';
|
|
||||||
|
|
||||||
const requiresRestartKeys = [
|
|
||||||
'bindAddress',
|
|
||||||
'port',
|
|
||||||
'urlBase',
|
|
||||||
'instanceName',
|
|
||||||
'enableSsl',
|
|
||||||
'sslPort',
|
|
||||||
'sslCertHash',
|
|
||||||
'sslCertPassword'
|
|
||||||
];
|
|
||||||
|
|
||||||
class GeneralSettings extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isRestartRequiredModalOpen: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
|
||||||
const {
|
|
||||||
settings,
|
|
||||||
isSaving,
|
|
||||||
saveError,
|
|
||||||
isResettingApiKey
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (!isResettingApiKey && prevProps.isResettingApiKey) {
|
|
||||||
this.setState({ isRestartRequiredModalOpen: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSaving || saveError || !prevProps.isSaving) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const prevSettings = prevProps.settings;
|
|
||||||
|
|
||||||
const pendingRestart = _.some(requiresRestartKeys, (key) => {
|
|
||||||
const setting = settings[key];
|
|
||||||
const prevSetting = prevSettings[key];
|
|
||||||
|
|
||||||
if (!setting || !prevSetting) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const previousValue = prevSetting.previousValue;
|
|
||||||
const value = setting.value;
|
|
||||||
|
|
||||||
return previousValue != null && previousValue !== value;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setState({ isRestartRequiredModalOpen: pendingRestart });
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onConfirmRestart = () => {
|
|
||||||
this.setState({ isRestartRequiredModalOpen: false });
|
|
||||||
this.props.onConfirmRestart();
|
|
||||||
};
|
|
||||||
|
|
||||||
onCloseRestartRequiredModalOpen = () => {
|
|
||||||
this.setState({ isRestartRequiredModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
advancedSettings,
|
|
||||||
isFetching,
|
|
||||||
isPopulated,
|
|
||||||
error,
|
|
||||||
settings,
|
|
||||||
hasSettings,
|
|
||||||
isResettingApiKey,
|
|
||||||
isWindows,
|
|
||||||
isWindowsService,
|
|
||||||
mode,
|
|
||||||
packageUpdateMechanism,
|
|
||||||
onInputChange,
|
|
||||||
onConfirmResetApiKey,
|
|
||||||
...otherProps
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PageContent title={translate('GeneralSettings')}>
|
|
||||||
<SettingsToolbar
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<PageContentBody>
|
|
||||||
{
|
|
||||||
isFetching && !isPopulated &&
|
|
||||||
<LoadingIndicator />
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
!isFetching && error &&
|
|
||||||
<Alert kind={kinds.DANGER}>
|
|
||||||
{translate('GeneralSettingsLoadError')}
|
|
||||||
</Alert>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
hasSettings && isPopulated && !error &&
|
|
||||||
<Form
|
|
||||||
id="generalSettings"
|
|
||||||
{...otherProps}
|
|
||||||
>
|
|
||||||
<HostSettings
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
settings={settings}
|
|
||||||
isWindows={isWindows}
|
|
||||||
mode={mode}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SecuritySettings
|
|
||||||
settings={settings}
|
|
||||||
isResettingApiKey={isResettingApiKey}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
onConfirmResetApiKey={onConfirmResetApiKey}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ProxySettings
|
|
||||||
settings={settings}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<LoggingSettings
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
settings={settings}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AnalyticSettings
|
|
||||||
settings={settings}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UpdateSettings
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
settings={settings}
|
|
||||||
isWindows={isWindows}
|
|
||||||
packageUpdateMechanism={packageUpdateMechanism}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<BackupSettings
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
settings={settings}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</Form>
|
|
||||||
}
|
|
||||||
</PageContentBody>
|
|
||||||
|
|
||||||
<ConfirmModal
|
|
||||||
isOpen={this.state.isRestartRequiredModalOpen}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
title={translate('RestartSonarr')}
|
|
||||||
message={`${translate('RestartRequiredToApplyChanges')} ${isWindowsService ? translate('RestartRequiredWindowsService') : ''}`}
|
|
||||||
cancelLabel={translate('RestartLater')}
|
|
||||||
confirmLabel={translate('RestartNow')}
|
|
||||||
onConfirm={this.onConfirmRestart}
|
|
||||||
onCancel={this.onCloseRestartRequiredModalOpen}
|
|
||||||
/>
|
|
||||||
</PageContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GeneralSettings.propTypes = {
|
|
||||||
advancedSettings: PropTypes.bool.isRequired,
|
|
||||||
isFetching: PropTypes.bool.isRequired,
|
|
||||||
isPopulated: PropTypes.bool.isRequired,
|
|
||||||
error: PropTypes.object,
|
|
||||||
isSaving: PropTypes.bool.isRequired,
|
|
||||||
saveError: PropTypes.object,
|
|
||||||
settings: PropTypes.object.isRequired,
|
|
||||||
isResettingApiKey: PropTypes.bool.isRequired,
|
|
||||||
hasSettings: PropTypes.bool.isRequired,
|
|
||||||
isWindows: PropTypes.bool.isRequired,
|
|
||||||
isWindowsService: PropTypes.bool.isRequired,
|
|
||||||
mode: PropTypes.string.isRequired,
|
|
||||||
packageUpdateMechanism: PropTypes.string.isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired,
|
|
||||||
onConfirmResetApiKey: PropTypes.func.isRequired,
|
|
||||||
onConfirmRestart: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default GeneralSettings;
|
|
@ -0,0 +1,233 @@
|
|||||||
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import * as commandNames from 'Commands/commandNames';
|
||||||
|
import Alert from 'Components/Alert';
|
||||||
|
import Form from 'Components/Form/Form';
|
||||||
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
|
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
|
import PageContent from 'Components/Page/PageContent';
|
||||||
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
|
import usePrevious from 'Helpers/Hooks/usePrevious';
|
||||||
|
import { kinds } from 'Helpers/Props';
|
||||||
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
|
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
||||||
|
import {
|
||||||
|
fetchGeneralSettings,
|
||||||
|
saveGeneralSettings,
|
||||||
|
setGeneralSettingsValue,
|
||||||
|
} from 'Store/Actions/settingsActions';
|
||||||
|
import { restart } from 'Store/Actions/systemActions';
|
||||||
|
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||||
|
import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector';
|
||||||
|
import useIsWindowsService from 'System/useIsWindowsService';
|
||||||
|
import { InputChanged } from 'typings/inputs';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
import AnalyticSettings from './AnalyticSettings';
|
||||||
|
import BackupSettings from './BackupSettings';
|
||||||
|
import HostSettings from './HostSettings';
|
||||||
|
import LoggingSettings from './LoggingSettings';
|
||||||
|
import ProxySettings from './ProxySettings';
|
||||||
|
import SecuritySettings from './SecuritySettings';
|
||||||
|
import UpdateSettings from './UpdateSettings';
|
||||||
|
|
||||||
|
const SECTION = 'general';
|
||||||
|
|
||||||
|
const requiresRestartKeys = [
|
||||||
|
'bindAddress',
|
||||||
|
'port',
|
||||||
|
'urlBase',
|
||||||
|
'instanceName',
|
||||||
|
'enableSsl',
|
||||||
|
'sslPort',
|
||||||
|
'sslCertHash',
|
||||||
|
'sslCertPassword',
|
||||||
|
];
|
||||||
|
|
||||||
|
function GeneralSettings() {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const isWindowsService = useIsWindowsService();
|
||||||
|
const isResettingApiKey = useSelector(
|
||||||
|
createCommandExecutingSelector(commandNames.RESET_API_KEY)
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
isFetching,
|
||||||
|
isPopulated,
|
||||||
|
isSaving,
|
||||||
|
error,
|
||||||
|
saveError,
|
||||||
|
settings,
|
||||||
|
hasSettings,
|
||||||
|
hasPendingChanges,
|
||||||
|
pendingChanges,
|
||||||
|
validationErrors,
|
||||||
|
validationWarnings,
|
||||||
|
} = useSelector(createSettingsSectionSelector(SECTION));
|
||||||
|
|
||||||
|
const wasResettingApiKey = usePrevious(isResettingApiKey);
|
||||||
|
const wasSaving = usePrevious(isSaving);
|
||||||
|
const previousPendingChanges = usePrevious(pendingChanges);
|
||||||
|
|
||||||
|
const [isRestartRequiredModalOpen, setIsRestartRequiredModalOpen] =
|
||||||
|
useState(false);
|
||||||
|
|
||||||
|
const handleInputChange = useCallback(
|
||||||
|
(change: InputChanged) => {
|
||||||
|
// @ts-expect-error - actions aren't typed
|
||||||
|
dispatch(setGeneralSettingsValue(change));
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSavePress = useCallback(() => {
|
||||||
|
dispatch(saveGeneralSettings());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const handleConfirmRestart = useCallback(() => {
|
||||||
|
setIsRestartRequiredModalOpen(false);
|
||||||
|
dispatch(restart());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const handleCloseRestartRequiredModalOpen = useCallback(() => {
|
||||||
|
setIsRestartRequiredModalOpen(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(fetchGeneralSettings());
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
dispatch(clearPendingChanges({ section: `settings.${SECTION}` }));
|
||||||
|
};
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isResettingApiKey && wasResettingApiKey) {
|
||||||
|
dispatch(fetchGeneralSettings());
|
||||||
|
}
|
||||||
|
}, [isResettingApiKey, wasResettingApiKey, dispatch]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const isRestartedRequired =
|
||||||
|
previousPendingChanges &&
|
||||||
|
Object.keys(previousPendingChanges).some((key) => {
|
||||||
|
return requiresRestartKeys.includes(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isSaving && wasSaving && !saveError && isRestartedRequired) {
|
||||||
|
setIsRestartRequiredModalOpen(true);
|
||||||
|
}
|
||||||
|
}, [isSaving, wasSaving, saveError, previousPendingChanges]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isResettingApiKey && wasResettingApiKey) {
|
||||||
|
setIsRestartRequiredModalOpen(true);
|
||||||
|
}
|
||||||
|
}, [isResettingApiKey, wasResettingApiKey]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContent title={translate('GeneralSettings')}>
|
||||||
|
<SettingsToolbar
|
||||||
|
hasPendingChanges={hasPendingChanges}
|
||||||
|
isSaving={isSaving}
|
||||||
|
onSavePress={handleSavePress}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PageContentBody>
|
||||||
|
{isFetching && !isPopulated ? <LoadingIndicator /> : null}
|
||||||
|
|
||||||
|
{!isFetching && error ? (
|
||||||
|
<Alert kind={kinds.DANGER}>
|
||||||
|
{translate('GeneralSettingsLoadError')}
|
||||||
|
</Alert>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{hasSettings && isPopulated && !error ? (
|
||||||
|
<Form
|
||||||
|
id="generalSettings"
|
||||||
|
validationErrors={validationErrors}
|
||||||
|
validationWarnings={validationWarnings}
|
||||||
|
>
|
||||||
|
<HostSettings
|
||||||
|
bindAddress={settings.bindAddress}
|
||||||
|
port={settings.port}
|
||||||
|
urlBase={settings.urlBase}
|
||||||
|
instanceName={settings.instanceName}
|
||||||
|
applicationUrl={settings.applicationUrl}
|
||||||
|
enableSsl={settings.enableSsl}
|
||||||
|
sslPort={settings.sslPort}
|
||||||
|
sslCertPath={settings.sslCertPath}
|
||||||
|
sslCertPassword={settings.sslCertPassword}
|
||||||
|
launchBrowser={settings.launchBrowser}
|
||||||
|
onInputChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SecuritySettings
|
||||||
|
authenticationMethod={settings.authenticationMethod}
|
||||||
|
authenticationRequired={settings.authenticationRequired}
|
||||||
|
username={settings.username}
|
||||||
|
password={settings.password}
|
||||||
|
passwordConfirmation={settings.passwordConfirmation}
|
||||||
|
apiKey={settings.apiKey}
|
||||||
|
certificateValidation={settings.certificateValidation}
|
||||||
|
isResettingApiKey={isResettingApiKey}
|
||||||
|
onInputChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ProxySettings
|
||||||
|
proxyEnabled={settings.proxyEnabled}
|
||||||
|
proxyType={settings.proxyType}
|
||||||
|
proxyHostname={settings.proxyHostname}
|
||||||
|
proxyPort={settings.proxyPort}
|
||||||
|
proxyUsername={settings.proxyUsername}
|
||||||
|
proxyPassword={settings.proxyPassword}
|
||||||
|
proxyBypassFilter={settings.proxyBypassFilter}
|
||||||
|
proxyBypassLocalAddresses={settings.proxyBypassLocalAddresses}
|
||||||
|
onInputChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LoggingSettings
|
||||||
|
logLevel={settings.logLevel}
|
||||||
|
logSizeLimit={settings.logSizeLimit}
|
||||||
|
onInputChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AnalyticSettings
|
||||||
|
analyticsEnabled={settings.analyticsEnabled}
|
||||||
|
onInputChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UpdateSettings
|
||||||
|
branch={settings.branch}
|
||||||
|
updateAutomatically={settings.updateAutomatically}
|
||||||
|
updateMechanism={settings.updateMechanism}
|
||||||
|
updateScriptPath={settings.updateScriptPath}
|
||||||
|
onInputChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BackupSettings
|
||||||
|
backupFolder={settings.backupFolder}
|
||||||
|
backupInterval={settings.backupInterval}
|
||||||
|
backupRetention={settings.backupRetention}
|
||||||
|
onInputChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
) : null}
|
||||||
|
</PageContentBody>
|
||||||
|
|
||||||
|
<ConfirmModal
|
||||||
|
isOpen={isRestartRequiredModalOpen}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
title={translate('RestartSonarr')}
|
||||||
|
message={`${translate('RestartRequiredToApplyChanges')} ${
|
||||||
|
isWindowsService ? translate('RestartRequiredWindowsService') : ''
|
||||||
|
}`}
|
||||||
|
cancelLabel={translate('RestartLater')}
|
||||||
|
confirmLabel={translate('RestartNow')}
|
||||||
|
onConfirm={handleConfirmRestart}
|
||||||
|
onCancel={handleCloseRestartRequiredModalOpen}
|
||||||
|
/>
|
||||||
|
</PageContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GeneralSettings;
|
@ -1,110 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import * as commandNames from 'Commands/commandNames';
|
|
||||||
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
|
||||||
import { executeCommand } from 'Store/Actions/commandActions';
|
|
||||||
import { fetchGeneralSettings, saveGeneralSettings, setGeneralSettingsValue } from 'Store/Actions/settingsActions';
|
|
||||||
import { restart } from 'Store/Actions/systemActions';
|
|
||||||
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
|
||||||
import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector';
|
|
||||||
import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector';
|
|
||||||
import GeneralSettings from './GeneralSettings';
|
|
||||||
|
|
||||||
const SECTION = 'general';
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
(state) => state.settings.advancedSettings,
|
|
||||||
createSettingsSectionSelector(SECTION),
|
|
||||||
createCommandExecutingSelector(commandNames.RESET_API_KEY),
|
|
||||||
createSystemStatusSelector(),
|
|
||||||
(advancedSettings, sectionSettings, isResettingApiKey, systemStatus) => {
|
|
||||||
return {
|
|
||||||
advancedSettings,
|
|
||||||
isResettingApiKey,
|
|
||||||
isWindows: systemStatus.isWindows,
|
|
||||||
isWindowsService: systemStatus.isWindows && systemStatus.mode === 'service',
|
|
||||||
mode: systemStatus.mode,
|
|
||||||
packageUpdateMechanism: systemStatus.packageUpdateMechanism,
|
|
||||||
...sectionSettings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
setGeneralSettingsValue,
|
|
||||||
saveGeneralSettings,
|
|
||||||
fetchGeneralSettings,
|
|
||||||
executeCommand,
|
|
||||||
restart,
|
|
||||||
clearPendingChanges
|
|
||||||
};
|
|
||||||
|
|
||||||
class GeneralSettingsConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.props.fetchGeneralSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
|
||||||
if (!this.props.isResettingApiKey && prevProps.isResettingApiKey) {
|
|
||||||
this.props.fetchGeneralSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.props.clearPendingChanges({ section: `settings.${SECTION}` });
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onInputChange = ({ name, value }) => {
|
|
||||||
this.props.setGeneralSettingsValue({ name, value });
|
|
||||||
};
|
|
||||||
|
|
||||||
onSavePress = () => {
|
|
||||||
this.props.saveGeneralSettings();
|
|
||||||
};
|
|
||||||
|
|
||||||
onConfirmResetApiKey = () => {
|
|
||||||
this.props.executeCommand({ name: commandNames.RESET_API_KEY });
|
|
||||||
};
|
|
||||||
|
|
||||||
onConfirmRestart = () => {
|
|
||||||
this.props.restart();
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<GeneralSettings
|
|
||||||
onInputChange={this.onInputChange}
|
|
||||||
onSavePress={this.onSavePress}
|
|
||||||
onConfirmResetApiKey={this.onConfirmResetApiKey}
|
|
||||||
onConfirmRestart={this.onConfirmRestart}
|
|
||||||
{...this.props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GeneralSettingsConnector.propTypes = {
|
|
||||||
isResettingApiKey: PropTypes.bool.isRequired,
|
|
||||||
setGeneralSettingsValue: PropTypes.func.isRequired,
|
|
||||||
saveGeneralSettings: PropTypes.func.isRequired,
|
|
||||||
fetchGeneralSettings: PropTypes.func.isRequired,
|
|
||||||
executeCommand: PropTypes.func.isRequired,
|
|
||||||
restart: PropTypes.func.isRequired,
|
|
||||||
clearPendingChanges: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps, mapDispatchToProps)(GeneralSettingsConnector);
|
|
@ -1,214 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import FieldSet from 'Components/FieldSet';
|
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
|
||||||
import { inputTypes, sizes } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
|
|
||||||
function HostSettings(props) {
|
|
||||||
const {
|
|
||||||
advancedSettings,
|
|
||||||
settings,
|
|
||||||
isWindows,
|
|
||||||
mode,
|
|
||||||
onInputChange
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const {
|
|
||||||
bindAddress,
|
|
||||||
port,
|
|
||||||
urlBase,
|
|
||||||
instanceName,
|
|
||||||
applicationUrl,
|
|
||||||
enableSsl,
|
|
||||||
sslPort,
|
|
||||||
sslCertPath,
|
|
||||||
sslCertPassword,
|
|
||||||
launchBrowser
|
|
||||||
} = settings;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FieldSet legend={translate('Host')}>
|
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('BindAddress')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="bindAddress"
|
|
||||||
helpText={translate('BindAddressHelpText')}
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...bindAddress}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('PortNumber')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.NUMBER}
|
|
||||||
name="port"
|
|
||||||
min={1}
|
|
||||||
max={65535}
|
|
||||||
autocomplete="off"
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...port}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('UrlBase')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="urlBase"
|
|
||||||
helpText={translate('UrlBaseHelpText')}
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...urlBase}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('InstanceName')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="instanceName"
|
|
||||||
helpText={translate('InstanceNameHelpText')}
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...instanceName}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('ApplicationURL')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="applicationUrl"
|
|
||||||
helpText={translate('ApplicationUrlHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...applicationUrl}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
size={sizes.MEDIUM}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('EnableSsl')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="enableSsl"
|
|
||||||
helpText={translate('EnableSslHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...enableSsl}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
{
|
|
||||||
enableSsl.value ?
|
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('SslPort')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.NUMBER}
|
|
||||||
name="sslPort"
|
|
||||||
min={1}
|
|
||||||
max={65535}
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...sslPort}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
enableSsl.value ?
|
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('SslCertPath')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="sslCertPath"
|
|
||||||
helpText={translate('SslCertPathHelpText')}
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...sslCertPath}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
enableSsl.value ?
|
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('SslCertPassword')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.PASSWORD}
|
|
||||||
name="sslCertPassword"
|
|
||||||
helpText={translate('SslCertPasswordHelpText')}
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...sslCertPassword}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
isWindows && mode !== 'service' ?
|
|
||||||
<FormGroup size={sizes.MEDIUM}>
|
|
||||||
<FormLabel>{translate('OpenBrowserOnStart')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="launchBrowser"
|
|
||||||
helpText={translate('OpenBrowserOnStartHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...launchBrowser}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
</FieldSet>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
HostSettings.propTypes = {
|
|
||||||
advancedSettings: PropTypes.bool.isRequired,
|
|
||||||
settings: PropTypes.object.isRequired,
|
|
||||||
isWindows: PropTypes.bool.isRequired,
|
|
||||||
mode: PropTypes.string.isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default HostSettings;
|
|
@ -0,0 +1,191 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import FieldSet from 'Components/FieldSet';
|
||||||
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
|
import useShowAdvancedSettings from 'Helpers/Hooks/useShowAdvancedSettings';
|
||||||
|
import { inputTypes, sizes } from 'Helpers/Props';
|
||||||
|
import useIsWindowsService from 'System/useIsWindowsService';
|
||||||
|
import { InputChanged } from 'typings/inputs';
|
||||||
|
import { PendingSection } from 'typings/pending';
|
||||||
|
import General from 'typings/Settings/General';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
|
||||||
|
interface HostSettingsProps {
|
||||||
|
bindAddress: PendingSection<General>['bindAddress'];
|
||||||
|
port: PendingSection<General>['port'];
|
||||||
|
urlBase: PendingSection<General>['urlBase'];
|
||||||
|
instanceName: PendingSection<General>['instanceName'];
|
||||||
|
applicationUrl: PendingSection<General>['applicationUrl'];
|
||||||
|
enableSsl: PendingSection<General>['enableSsl'];
|
||||||
|
sslPort: PendingSection<General>['sslPort'];
|
||||||
|
sslCertPath: PendingSection<General>['sslCertPath'];
|
||||||
|
sslCertPassword: PendingSection<General>['sslCertPassword'];
|
||||||
|
launchBrowser: PendingSection<General>['launchBrowser'];
|
||||||
|
onInputChange: (change: InputChanged) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function HostSettings({
|
||||||
|
bindAddress,
|
||||||
|
port,
|
||||||
|
urlBase,
|
||||||
|
instanceName,
|
||||||
|
applicationUrl,
|
||||||
|
enableSsl,
|
||||||
|
sslPort,
|
||||||
|
sslCertPath,
|
||||||
|
sslCertPassword,
|
||||||
|
launchBrowser,
|
||||||
|
onInputChange,
|
||||||
|
}: HostSettingsProps) {
|
||||||
|
const showAdvancedSettings = useShowAdvancedSettings();
|
||||||
|
const isWindowsService = useIsWindowsService();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FieldSet legend={translate('Host')}>
|
||||||
|
<FormGroup advancedSettings={showAdvancedSettings} isAdvanced={true}>
|
||||||
|
<FormLabel>{translate('BindAddress')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="bindAddress"
|
||||||
|
helpText={translate('BindAddressHelpText')}
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...bindAddress}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('PortNumber')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.NUMBER}
|
||||||
|
name="port"
|
||||||
|
min={1}
|
||||||
|
max={65535}
|
||||||
|
autocomplete="off"
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...port}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('UrlBase')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="urlBase"
|
||||||
|
helpText={translate('UrlBaseHelpText')}
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...urlBase}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup advancedSettings={showAdvancedSettings} isAdvanced={true}>
|
||||||
|
<FormLabel>{translate('InstanceName')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="instanceName"
|
||||||
|
helpText={translate('InstanceNameHelpText')}
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...instanceName}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup advancedSettings={showAdvancedSettings} isAdvanced={true}>
|
||||||
|
<FormLabel>{translate('ApplicationURL')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="applicationUrl"
|
||||||
|
helpText={translate('ApplicationUrlHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...applicationUrl}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup
|
||||||
|
advancedSettings={showAdvancedSettings}
|
||||||
|
isAdvanced={true}
|
||||||
|
size={sizes.MEDIUM}
|
||||||
|
>
|
||||||
|
<FormLabel>{translate('EnableSsl')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="enableSsl"
|
||||||
|
helpText={translate('EnableSslHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...enableSsl}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
{enableSsl.value ? (
|
||||||
|
<FormGroup advancedSettings={showAdvancedSettings} isAdvanced={true}>
|
||||||
|
<FormLabel>{translate('SslPort')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.NUMBER}
|
||||||
|
name="sslPort"
|
||||||
|
min={1}
|
||||||
|
max={65535}
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...sslPort}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{enableSsl.value ? (
|
||||||
|
<FormGroup advancedSettings={showAdvancedSettings} isAdvanced={true}>
|
||||||
|
<FormLabel>{translate('SslCertPath')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="sslCertPath"
|
||||||
|
helpText={translate('SslCertPathHelpText')}
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...sslCertPath}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{enableSsl.value ? (
|
||||||
|
<FormGroup advancedSettings={showAdvancedSettings} isAdvanced={true}>
|
||||||
|
<FormLabel>{translate('SslCertPassword')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.PASSWORD}
|
||||||
|
name="sslCertPassword"
|
||||||
|
helpText={translate('SslCertPasswordHelpText')}
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...sslCertPassword}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{isWindowsService ? (
|
||||||
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
|
<FormLabel>{translate('OpenBrowserOnStart')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="launchBrowser"
|
||||||
|
helpText={translate('OpenBrowserOnStartHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...launchBrowser}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
</FieldSet>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HostSettings;
|
@ -1,152 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import FieldSet from 'Components/FieldSet';
|
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
|
||||||
import { inputTypes, sizes } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
|
|
||||||
function ProxySettings(props) {
|
|
||||||
const {
|
|
||||||
settings,
|
|
||||||
onInputChange
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const {
|
|
||||||
proxyEnabled,
|
|
||||||
proxyType,
|
|
||||||
proxyHostname,
|
|
||||||
proxyPort,
|
|
||||||
proxyUsername,
|
|
||||||
proxyPassword,
|
|
||||||
proxyBypassFilter,
|
|
||||||
proxyBypassLocalAddresses
|
|
||||||
} = settings;
|
|
||||||
|
|
||||||
const proxyTypeOptions = [
|
|
||||||
{
|
|
||||||
key: 'http',
|
|
||||||
value: translate('HttpHttps')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'socks4',
|
|
||||||
value: translate('Socks4')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'socks5',
|
|
||||||
value: translate('Socks5')
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FieldSet legend={translate('Proxy')}>
|
|
||||||
<FormGroup size={sizes.MEDIUM}>
|
|
||||||
<FormLabel>{translate('UseProxy')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="proxyEnabled"
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyEnabled}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
{
|
|
||||||
proxyEnabled.value &&
|
|
||||||
<div>
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('ProxyType')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.SELECT}
|
|
||||||
name="proxyType"
|
|
||||||
values={proxyTypeOptions}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyType}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Hostname')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="proxyHostname"
|
|
||||||
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyHostname}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Port')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.NUMBER}
|
|
||||||
name="proxyPort"
|
|
||||||
min={1}
|
|
||||||
max={65535}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyPort}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Username')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="proxyUsername"
|
|
||||||
helpText={translate('ProxyUsernameHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyUsername}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Password')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.PASSWORD}
|
|
||||||
name="proxyPassword"
|
|
||||||
helpText={translate('ProxyPasswordHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyPassword}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('IgnoredAddresses')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="proxyBypassFilter"
|
|
||||||
helpText={translate('ProxyBypassFilterHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyBypassFilter}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup size={sizes.MEDIUM}>
|
|
||||||
<FormLabel>{translate('BypassProxyForLocalAddresses')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="proxyBypassLocalAddresses"
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...proxyBypassLocalAddresses}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</FieldSet>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProxySettings.propTypes = {
|
|
||||||
settings: PropTypes.object.isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProxySettings;
|
|
@ -0,0 +1,153 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import FieldSet from 'Components/FieldSet';
|
||||||
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
|
import { inputTypes, sizes } from 'Helpers/Props';
|
||||||
|
import { InputChanged } from 'typings/inputs';
|
||||||
|
import { PendingSection } from 'typings/pending';
|
||||||
|
import General from 'typings/Settings/General';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
|
||||||
|
interface ProxySettingsProps {
|
||||||
|
proxyEnabled: PendingSection<General>['proxyEnabled'];
|
||||||
|
proxyType: PendingSection<General>['proxyType'];
|
||||||
|
proxyHostname: PendingSection<General>['proxyHostname'];
|
||||||
|
proxyPort: PendingSection<General>['proxyPort'];
|
||||||
|
proxyUsername: PendingSection<General>['proxyUsername'];
|
||||||
|
proxyPassword: PendingSection<General>['proxyPassword'];
|
||||||
|
proxyBypassFilter: PendingSection<General>['proxyBypassFilter'];
|
||||||
|
proxyBypassLocalAddresses: PendingSection<General>['proxyBypassLocalAddresses'];
|
||||||
|
onInputChange: (change: InputChanged) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProxySettings({
|
||||||
|
proxyEnabled,
|
||||||
|
proxyType,
|
||||||
|
proxyHostname,
|
||||||
|
proxyPort,
|
||||||
|
proxyUsername,
|
||||||
|
proxyPassword,
|
||||||
|
proxyBypassFilter,
|
||||||
|
proxyBypassLocalAddresses,
|
||||||
|
onInputChange,
|
||||||
|
}: ProxySettingsProps) {
|
||||||
|
const proxyTypeOptions = [
|
||||||
|
{
|
||||||
|
key: 'http',
|
||||||
|
value: translate('HttpHttps'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'socks4',
|
||||||
|
value: translate('Socks4'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'socks5',
|
||||||
|
value: translate('Socks5'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FieldSet legend={translate('Proxy')}>
|
||||||
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
|
<FormLabel>{translate('UseProxy')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="proxyEnabled"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyEnabled}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
{proxyEnabled.value && (
|
||||||
|
<div>
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('ProxyType')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.SELECT}
|
||||||
|
name="proxyType"
|
||||||
|
values={proxyTypeOptions}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyType}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Hostname')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="proxyHostname"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyHostname}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Port')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.NUMBER}
|
||||||
|
name="proxyPort"
|
||||||
|
min={1}
|
||||||
|
max={65535}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyPort}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Username')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="proxyUsername"
|
||||||
|
helpText={translate('ProxyUsernameHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyUsername}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Password')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.PASSWORD}
|
||||||
|
name="proxyPassword"
|
||||||
|
helpText={translate('ProxyPasswordHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyPassword}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('IgnoredAddresses')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="proxyBypassFilter"
|
||||||
|
helpText={translate('ProxyBypassFilterHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyBypassFilter}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
|
<FormLabel>{translate('BypassProxyForLocalAddresses')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="proxyBypassLocalAddresses"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...proxyBypassLocalAddresses}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</FieldSet>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProxySettings;
|
@ -1,278 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import FieldSet from 'Components/FieldSet';
|
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
|
||||||
import FormInputButton from 'Components/Form/FormInputButton';
|
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import ClipboardButton from 'Components/Link/ClipboardButton';
|
|
||||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
|
||||||
import { icons, inputTypes, kinds } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
|
|
||||||
export const authenticationMethodOptions = [
|
|
||||||
{
|
|
||||||
key: 'none',
|
|
||||||
get value() {
|
|
||||||
return translate('None');
|
|
||||||
},
|
|
||||||
isDisabled: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'external',
|
|
||||||
get value() {
|
|
||||||
return translate('External');
|
|
||||||
},
|
|
||||||
isHidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'basic',
|
|
||||||
get value() {
|
|
||||||
return translate('AuthBasic');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'forms',
|
|
||||||
get value() {
|
|
||||||
return translate('AuthForm');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export const authenticationRequiredOptions = [
|
|
||||||
{
|
|
||||||
key: 'enabled',
|
|
||||||
get value() {
|
|
||||||
return translate('Enabled');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'disabledForLocalAddresses',
|
|
||||||
get value() {
|
|
||||||
return translate('DisabledForLocalAddresses');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const certificateValidationOptions = [
|
|
||||||
{
|
|
||||||
key: 'enabled',
|
|
||||||
get value() {
|
|
||||||
return translate('Enabled');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'disabledForLocalAddresses',
|
|
||||||
get value() {
|
|
||||||
return translate('DisabledForLocalAddresses');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'disabled',
|
|
||||||
get value() {
|
|
||||||
return translate('Disabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
class SecuritySettings extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isConfirmApiKeyResetModalOpen: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onApikeyFocus = (event) => {
|
|
||||||
event.target.select();
|
|
||||||
};
|
|
||||||
|
|
||||||
onResetApiKeyPress = () => {
|
|
||||||
this.setState({ isConfirmApiKeyResetModalOpen: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
onConfirmResetApiKey = () => {
|
|
||||||
this.setState({ isConfirmApiKeyResetModalOpen: false });
|
|
||||||
this.props.onConfirmResetApiKey();
|
|
||||||
};
|
|
||||||
|
|
||||||
onCloseResetApiKeyModal = () => {
|
|
||||||
this.setState({ isConfirmApiKeyResetModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
settings,
|
|
||||||
isResettingApiKey,
|
|
||||||
onInputChange
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const {
|
|
||||||
authenticationMethod,
|
|
||||||
authenticationRequired,
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
passwordConfirmation,
|
|
||||||
apiKey,
|
|
||||||
certificateValidation
|
|
||||||
} = settings;
|
|
||||||
|
|
||||||
const authenticationEnabled = authenticationMethod && authenticationMethod.value !== 'none';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FieldSet legend={translate('Security')}>
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Authentication')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.SELECT}
|
|
||||||
name="authenticationMethod"
|
|
||||||
values={authenticationMethodOptions}
|
|
||||||
helpText={translate('AuthenticationMethodHelpText')}
|
|
||||||
helpTextWarning={translate('AuthenticationRequiredWarning')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...authenticationMethod}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
{
|
|
||||||
authenticationEnabled ?
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('AuthenticationRequired')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.SELECT}
|
|
||||||
name="authenticationRequired"
|
|
||||||
values={authenticationRequiredOptions}
|
|
||||||
helpText={translate('AuthenticationRequiredHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...authenticationRequired}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
authenticationEnabled ?
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Username')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="username"
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...username}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
authenticationEnabled ?
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Password')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.PASSWORD}
|
|
||||||
name="password"
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...password}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
authenticationEnabled ?
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('PasswordConfirmation')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.PASSWORD}
|
|
||||||
name="passwordConfirmation"
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...passwordConfirmation}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('ApiKey')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="apiKey"
|
|
||||||
readOnly={true}
|
|
||||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
|
||||||
buttons={[
|
|
||||||
<ClipboardButton
|
|
||||||
key="copy"
|
|
||||||
value={apiKey.value}
|
|
||||||
kind={kinds.DEFAULT}
|
|
||||||
/>,
|
|
||||||
|
|
||||||
<FormInputButton
|
|
||||||
key="reset"
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
onPress={this.onResetApiKeyPress}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
name={icons.REFRESH}
|
|
||||||
isSpinning={isResettingApiKey}
|
|
||||||
/>
|
|
||||||
</FormInputButton>
|
|
||||||
]}
|
|
||||||
onChange={onInputChange}
|
|
||||||
onFocus={this.onApikeyFocus}
|
|
||||||
{...apiKey}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('CertificateValidation')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.SELECT}
|
|
||||||
name="certificateValidation"
|
|
||||||
values={certificateValidationOptions}
|
|
||||||
helpText={translate('CertificateValidationHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...certificateValidation}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<ConfirmModal
|
|
||||||
isOpen={this.state.isConfirmApiKeyResetModalOpen}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
title={translate('ResetAPIKey')}
|
|
||||||
message={translate('ResetAPIKeyMessageText')}
|
|
||||||
confirmLabel={translate('Reset')}
|
|
||||||
onConfirm={this.onConfirmResetApiKey}
|
|
||||||
onCancel={this.onCloseResetApiKeyModal}
|
|
||||||
/>
|
|
||||||
</FieldSet>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SecuritySettings.propTypes = {
|
|
||||||
settings: PropTypes.object.isRequired,
|
|
||||||
isResettingApiKey: PropTypes.bool.isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired,
|
|
||||||
onConfirmResetApiKey: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SecuritySettings;
|
|
@ -0,0 +1,263 @@
|
|||||||
|
import React, { FocusEvent, useCallback, useState } from 'react';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import * as commandNames from 'Commands/commandNames';
|
||||||
|
import FieldSet from 'Components/FieldSet';
|
||||||
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
|
import FormInputButton from 'Components/Form/FormInputButton';
|
||||||
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
|
import Icon from 'Components/Icon';
|
||||||
|
import ClipboardButton from 'Components/Link/ClipboardButton';
|
||||||
|
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
|
import { icons, inputTypes, kinds } from 'Helpers/Props';
|
||||||
|
import { executeCommand } from 'Store/Actions/commandActions';
|
||||||
|
import { InputChanged } from 'typings/inputs';
|
||||||
|
import { PendingSection } from 'typings/pending';
|
||||||
|
import General from 'typings/Settings/General';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
|
||||||
|
export const authenticationMethodOptions = [
|
||||||
|
{
|
||||||
|
key: 'none',
|
||||||
|
get value() {
|
||||||
|
return translate('None');
|
||||||
|
},
|
||||||
|
isDisabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'external',
|
||||||
|
get value() {
|
||||||
|
return translate('External');
|
||||||
|
},
|
||||||
|
isHidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'basic',
|
||||||
|
get value() {
|
||||||
|
return translate('AuthBasic');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'forms',
|
||||||
|
get value() {
|
||||||
|
return translate('AuthForm');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const authenticationRequiredOptions = [
|
||||||
|
{
|
||||||
|
key: 'enabled',
|
||||||
|
get value() {
|
||||||
|
return translate('Enabled');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'disabledForLocalAddresses',
|
||||||
|
get value() {
|
||||||
|
return translate('DisabledForLocalAddresses');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const certificateValidationOptions = [
|
||||||
|
{
|
||||||
|
key: 'enabled',
|
||||||
|
get value() {
|
||||||
|
return translate('Enabled');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'disabledForLocalAddresses',
|
||||||
|
get value() {
|
||||||
|
return translate('DisabledForLocalAddresses');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'disabled',
|
||||||
|
get value() {
|
||||||
|
return translate('Disabled');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
interface SecuritySettingsProps {
|
||||||
|
authenticationMethod: PendingSection<General>['authenticationMethod'];
|
||||||
|
authenticationRequired: PendingSection<General>['authenticationRequired'];
|
||||||
|
username: PendingSection<General>['username'];
|
||||||
|
password: PendingSection<General>['password'];
|
||||||
|
passwordConfirmation: PendingSection<General>['passwordConfirmation'];
|
||||||
|
apiKey: PendingSection<General>['apiKey'];
|
||||||
|
certificateValidation: PendingSection<General>['certificateValidation'];
|
||||||
|
isResettingApiKey: boolean;
|
||||||
|
onInputChange: (change: InputChanged) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SecuritySettings({
|
||||||
|
authenticationMethod,
|
||||||
|
authenticationRequired,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
passwordConfirmation,
|
||||||
|
apiKey,
|
||||||
|
certificateValidation,
|
||||||
|
isResettingApiKey,
|
||||||
|
onInputChange,
|
||||||
|
}: SecuritySettingsProps) {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const [isConfirmApiKeyResetModalOpen, setIsConfirmApiKeyResetModalOpen] =
|
||||||
|
useState(false);
|
||||||
|
|
||||||
|
const handleApikeyFocus = useCallback(
|
||||||
|
(event: FocusEvent<HTMLInputElement, Element>) => {
|
||||||
|
event.target.select();
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleResetApiKeyPress = useCallback(() => {
|
||||||
|
setIsConfirmApiKeyResetModalOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleConfirmResetApiKey = useCallback(() => {
|
||||||
|
setIsConfirmApiKeyResetModalOpen(false);
|
||||||
|
|
||||||
|
dispatch(executeCommand({ name: commandNames.RESET_API_KEY }));
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const handleCloseResetApiKeyModal = useCallback(() => {
|
||||||
|
setIsConfirmApiKeyResetModalOpen(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// createCommandExecutingSelector(commandNames.RESET_API_KEY),
|
||||||
|
|
||||||
|
const authenticationEnabled =
|
||||||
|
authenticationMethod && authenticationMethod.value !== 'none';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FieldSet legend={translate('Security')}>
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Authentication')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.SELECT}
|
||||||
|
name="authenticationMethod"
|
||||||
|
values={authenticationMethodOptions}
|
||||||
|
helpText={translate('AuthenticationMethodHelpText')}
|
||||||
|
helpTextWarning={translate('AuthenticationRequiredWarning')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...authenticationMethod}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
{authenticationEnabled ? (
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('AuthenticationRequired')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.SELECT}
|
||||||
|
name="authenticationRequired"
|
||||||
|
values={authenticationRequiredOptions}
|
||||||
|
helpText={translate('AuthenticationRequiredHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...authenticationRequired}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{authenticationEnabled ? (
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Username')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="username"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...username}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{authenticationEnabled ? (
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Password')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.PASSWORD}
|
||||||
|
name="password"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...password}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{authenticationEnabled ? (
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('PasswordConfirmation')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.PASSWORD}
|
||||||
|
name="passwordConfirmation"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...passwordConfirmation}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('ApiKey')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="apiKey"
|
||||||
|
readOnly={true}
|
||||||
|
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||||
|
buttons={[
|
||||||
|
<ClipboardButton
|
||||||
|
key="copy"
|
||||||
|
value={apiKey.value}
|
||||||
|
kind={kinds.DEFAULT}
|
||||||
|
/>,
|
||||||
|
|
||||||
|
<FormInputButton
|
||||||
|
key="reset"
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
onPress={handleResetApiKeyPress}
|
||||||
|
>
|
||||||
|
<Icon name={icons.REFRESH} isSpinning={isResettingApiKey} />
|
||||||
|
</FormInputButton>,
|
||||||
|
]}
|
||||||
|
onChange={onInputChange}
|
||||||
|
onFocus={handleApikeyFocus}
|
||||||
|
{...apiKey}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('CertificateValidation')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.SELECT}
|
||||||
|
name="certificateValidation"
|
||||||
|
values={certificateValidationOptions}
|
||||||
|
helpText={translate('CertificateValidationHelpText')}
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...certificateValidation}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<ConfirmModal
|
||||||
|
isOpen={isConfirmApiKeyResetModalOpen}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
title={translate('ResetAPIKey')}
|
||||||
|
message={translate('ResetAPIKeyMessageText')}
|
||||||
|
confirmLabel={translate('Reset')}
|
||||||
|
onConfirm={handleConfirmResetApiKey}
|
||||||
|
onCancel={handleCloseResetApiKeyModal}
|
||||||
|
/>
|
||||||
|
</FieldSet>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SecuritySettings;
|
@ -0,0 +1,9 @@
|
|||||||
|
import useSystemStatus from './useSystemStatus';
|
||||||
|
|
||||||
|
function useIsWindowsService() {
|
||||||
|
const { isWindows, mode } = useSystemStatus();
|
||||||
|
|
||||||
|
return isWindows && mode === 'service';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useIsWindowsService;
|
@ -0,0 +1,8 @@
|
|||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector';
|
||||||
|
|
||||||
|
function useSystemStatus() {
|
||||||
|
return useSelector(createSystemStatusSelector());
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useSystemStatus;
|
Loading…
Reference in new issue