fix: add support for ssl when connecting to plex

fixes #275
This commit is contained in:
sct
2020-12-15 03:22:54 +00:00
parent f998873fc5
commit 3ba09d07eb
5 changed files with 165 additions and 110 deletions

View File

@@ -2,21 +2,23 @@ import React, { useState } from 'react';
import LoadingSpinner from '../Common/LoadingSpinner';
import type { PlexSettings } from '../../../server/lib/settings';
import useSWR from 'swr';
import { useFormik } from 'formik';
import { Formik, Field } from 'formik';
import Button from '../Common/Button';
import axios from 'axios';
import LibraryItem from './LibraryItem';
import Badge from '../Common/Badge';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import * as Yup from 'yup';
const messages = defineMessages({
plexsettings: 'Plex Settings',
plexsettingsDescription:
'Configure the settings for your Plex server. Overseerr uses your Plex server to scan your library at an interval and see what content is available.',
servername: 'Server Name (Automatically Set)',
servername: 'Server Name (Automatically set after you save)',
servernamePlaceholder: 'Plex Server Name',
hostname: 'Hostname/IP',
port: 'Port',
ssl: 'SSL',
save: 'Save Changes',
saving: 'Saving...',
plexlibraries: 'Plex Libraries',
@@ -32,6 +34,8 @@ const messages = defineMessages({
librariesRemaining: 'Libraries Remaining: {count}',
startscan: 'Start Scan',
cancelscan: 'Cancel Scan',
validationHostnameRequired: 'You must provide a hostname/IP',
validationPortRequired: 'You must provide a port',
});
interface Library {
@@ -64,33 +68,15 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
}
);
const [isSyncing, setIsSyncing] = useState(false);
const [isUpdating, setIsUpdating] = useState(false);
const [submitError, setSubmitError] = useState<string | null>(null);
const formik = useFormik({
initialValues: {
hostname: data?.ip,
port: data?.port,
},
enableReinitialize: true,
onSubmit: async (values) => {
setSubmitError(null);
setIsUpdating(true);
try {
await axios.post('/api/v1/settings/plex', {
ip: values.hostname,
port: Number(values.port),
} as PlexSettings);
revalidate();
if (onComplete) {
onComplete();
}
} catch (e) {
setSubmitError(e.response.data.message);
} finally {
setIsUpdating(false);
}
},
const PlexSettingsSchema = Yup.object().shape({
hostname: Yup.string().required(
intl.formatMessage(messages.validationHostnameRequired)
),
port: Yup.number().required(
intl.formatMessage(messages.validationPortRequired)
),
});
const activeLibraries =
@@ -164,91 +150,154 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
<FormattedMessage {...messages.plexsettingsDescription} />
</p>
</div>
<form onSubmit={formik.handleSubmit}>
<div className="mt-6 sm:mt-5">
{submitError && (
<div className="bg-red-700 text-white p-4 rounded-md mb-6">
{submitError}
</div>
)}
<div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label
htmlFor="name"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
<FormattedMessage {...messages.servername} />
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm">
<input
type="text"
id="name"
name="name"
placeholder={intl.formatMessage(
messages.servernamePlaceholder
)}
value={data?.name}
readOnly
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500"
/>
<Formik
initialValues={{
hostname: data?.ip,
port: data?.port,
useSsl: data?.useSsl,
}}
enableReinitialize
validationSchema={PlexSettingsSchema}
onSubmit={async (values) => {
setSubmitError(null);
try {
await axios.post('/api/v1/settings/plex', {
ip: values.hostname,
port: Number(values.port),
useSsl: values.useSsl,
} as PlexSettings);
revalidate();
if (onComplete) {
onComplete();
}
} catch (e) {
setSubmitError(e.response.data.message);
}
}}
>
{({
errors,
touched,
values,
handleSubmit,
setFieldValue,
isSubmitting,
}) => {
return (
<form onSubmit={handleSubmit}>
<div className="mt-6 sm:mt-5">
{submitError && (
<div className="bg-red-700 text-white p-4 rounded-md mb-6">
{submitError}
</div>
)}
<div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label
htmlFor="name"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
<FormattedMessage {...messages.servername} />
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm">
<input
type="text"
id="name"
name="name"
placeholder={intl.formatMessage(
messages.servernamePlaceholder
)}
value={data?.name}
readOnly
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500"
/>
</div>
</div>
</div>
<div className="mt-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label
htmlFor="hostname"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
<FormattedMessage {...messages.hostname} />
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm">
<Field
type="text"
id="hostname"
name="hostname"
placeholder="127.0.0.1"
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500"
/>
</div>
{errors.hostname && touched.hostname && (
<div className="text-red-500 mt-2">{errors.hostname}</div>
)}
</div>
</div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label
htmlFor="port"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
<FormattedMessage {...messages.port} />
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<Field
type="text"
id="port"
name="port"
placeholder="32400"
className="form-input block w-24 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500"
/>
</div>
{errors.port && touched.port && (
<div className="text-red-500 mt-2">{errors.port}</div>
)}
</div>
</div>
</div>
</div>
</div>
<div className="mt-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label
htmlFor="hostname"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
<FormattedMessage {...messages.hostname} />
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm">
<input
type="text"
id="hostname"
name="hostname"
placeholder="127.0.0.1"
value={formik.values.hostname}
onChange={formik.handleChange}
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500"
/>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label
htmlFor="ssl"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
{intl.formatMessage(messages.ssl)}
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<Field
type="checkbox"
id="useSsl"
name="useSsl"
onChange={() => {
setFieldValue('useSsl', !values.useSsl);
}}
className="form-checkbox h-6 w-6 rounded-md text-indigo-600 transition duration-150 ease-in-out"
/>
</div>
</div>
</div>
</div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label
htmlFor="port"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
<FormattedMessage {...messages.port} />
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<input
type="text"
id="port"
name="port"
placeholder="32400"
value={formik.values.port}
onChange={formik.handleChange}
className="form-input block w-24 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500"
/>
<div className="mt-8 border-t border-gray-700 pt-5">
<div className="flex justify-end">
<span className="ml-3 inline-flex rounded-md shadow-sm">
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting}
>
{isSubmitting
? intl.formatMessage(messages.saving)
: intl.formatMessage(messages.save)}
</Button>
</span>
</div>
</div>
</div>
</div>
</div>
<div className="mt-8 border-t border-gray-700 pt-5">
<div className="flex justify-end">
<span className="ml-3 inline-flex rounded-md shadow-sm">
<Button buttonType="primary" type="submit" disabled={isUpdating}>
{isUpdating
? intl.formatMessage(messages.saving)
: intl.formatMessage(messages.save)}
</Button>
</span>
</div>
</div>
</form>
</form>
);
}}
</Formik>
<div className="mt-10">
<h3 className="text-lg leading-6 font-medium text-gray-200">
<FormattedMessage {...messages.plexlibraries} />