1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-18 21:35:27 -04:00
Files
Sonarr/frontend/src/Settings/General/SecuritySettings.tsx
T
2025-04-28 17:11:50 -07:00

268 lines
7.3 KiB
TypeScript

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 { EnhancedSelectInputValue } from 'Components/Form/Select/EnhancedSelectInput';
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: EnhancedSelectInputValue<string>[] = [
{
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');
},
isDisabled: true,
isHidden: true,
},
{
key: 'forms',
get value() {
return translate('AuthForm');
},
},
];
export const authenticationRequiredOptions: EnhancedSelectInputValue<string>[] =
[
{
key: 'enabled',
get value() {
return translate('Enabled');
},
},
{
key: 'disabledForLocalAddresses',
get value() {
return translate('DisabledForLocalAddresses');
},
},
];
const certificateValidationOptions: EnhancedSelectInputValue<string>[] = [
{
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;