import axios from 'axios'; import { Field, Form, Formik } from 'formik'; import React, { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useToasts } from 'react-toast-notifications'; import useSWR from 'swr'; import * as Yup from 'yup'; import globalMessages from '../../../i18n/globalMessages'; import Alert from '../../Common/Alert'; import Badge from '../../Common/Badge'; import Button from '../../Common/Button'; import LoadingSpinner from '../../Common/LoadingSpinner'; import SensitiveInput from '../../Common/SensitiveInput'; import NotificationTypeSelector from '../../NotificationTypeSelector'; const messages = defineMessages({ validationSmtpHostRequired: 'You must provide a valid hostname or IP address', validationSmtpPortRequired: 'You must provide a valid port number', agentenabled: 'Enable Agent', emailsender: 'Sender Address', smtpHost: 'SMTP Host', smtpPort: 'SMTP Port', enableSsl: 'Enable SSL', authUser: 'SMTP Username', authPass: 'SMTP Password', emailsettingssaved: 'Email notification settings saved successfully!', emailsettingsfailed: 'Email notification settings failed to save.', toastEmailTestSending: 'Sending email test notification…', toastEmailTestSuccess: 'Email test notification sent!', toastEmailTestFailed: 'Email test notification failed to send.', allowselfsigned: 'Allow Self-Signed Certificates', ssldisabletip: 'SSL should be disabled on standard TLS connections (port 587)', senderName: 'Sender Name', validationEmail: 'You must provide a valid email address', emailNotificationTypesAlertDescription: 'Media Requested, Media Automatically Approved, and Media Failed email notifications are sent to all users with the Manage Requests permission.', emailNotificationTypesAlertDescriptionPt2: 'Media Approved, Media Declined, and Media Available email notifications are sent to the user who submitted the request.', pgpPrivateKey: 'PGP Private Key', pgpPrivateKeyTip: 'Sign encrypted email messages using OpenPGP', validationPgpPrivateKey: 'You must provide a valid PGP private key if a PGP password is entered', pgpPassword: 'PGP Password', pgpPasswordTip: 'Sign encrypted email messages using OpenPGP', validationPgpPassword: 'You must provide a PGP password if a PGP private key is entered', }); export function OpenPgpLink(msg: string): JSX.Element { return ( {msg} ); } const NotificationsEmail: React.FC = () => { const intl = useIntl(); const { addToast, removeToast } = useToasts(); const [isTesting, setIsTesting] = useState(false); const { data, error, revalidate } = useSWR( '/api/v1/settings/notifications/email' ); const NotificationsEmailSchema = Yup.object().shape( { emailFrom: Yup.string() .when('enabled', { is: true, then: Yup.string() .nullable() .required(intl.formatMessage(messages.validationEmail)), otherwise: Yup.string().nullable(), }) .email(intl.formatMessage(messages.validationEmail)), smtpHost: Yup.string() .when('enabled', { is: true, then: Yup.string() .nullable() .required(intl.formatMessage(messages.validationSmtpHostRequired)), otherwise: Yup.string().nullable(), }) .matches( /^(([a-z]|\d|_|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*)?([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])$/i, intl.formatMessage(messages.validationSmtpHostRequired) ), smtpPort: Yup.number() .typeError(intl.formatMessage(messages.validationSmtpPortRequired)) .when('enabled', { is: true, then: Yup.number().required( intl.formatMessage(messages.validationSmtpPortRequired) ), otherwise: Yup.number().nullable(), }), pgpPrivateKey: Yup.string() .when('pgpPassword', { is: (value: unknown) => !!value, then: Yup.string() .nullable() .required(intl.formatMessage(messages.validationPgpPrivateKey)), otherwise: Yup.string().nullable(), }) .matches( /^-----BEGIN PGP PRIVATE KEY BLOCK-----.+-----END PGP PRIVATE KEY BLOCK-----$/, intl.formatMessage(messages.validationPgpPrivateKey) ), pgpPassword: Yup.string().when('pgpPrivateKey', { is: (value: unknown) => !!value, then: Yup.string() .nullable() .required(intl.formatMessage(messages.validationPgpPassword)), otherwise: Yup.string().nullable(), }), }, [['pgpPrivateKey', 'pgpPassword']] ); if (!data && !error) { return ; } return ( { try { await axios.post('/api/v1/settings/notifications/email', { enabled: values.enabled, types: values.types, options: { emailFrom: values.emailFrom, smtpHost: values.smtpHost, smtpPort: Number(values.smtpPort), secure: values.secure, authUser: values.authUser, authPass: values.authPass, allowSelfSigned: values.allowSelfSigned, senderName: values.senderName, pgpPrivateKey: values.pgpPrivateKey, pgpPassword: values.pgpPassword, }, }); addToast(intl.formatMessage(messages.emailsettingssaved), { appearance: 'success', autoDismiss: true, }); } catch (e) { addToast(intl.formatMessage(messages.emailsettingsfailed), { appearance: 'error', autoDismiss: true, }); } finally { revalidate(); } }} > {({ errors, touched, isSubmitting, values, isValid, setFieldValue }) => { const testSettings = async () => { setIsTesting(true); let toastId: string | undefined; try { addToast( intl.formatMessage(messages.toastEmailTestSending), { autoDismiss: false, appearance: 'info', }, (id) => { toastId = id; } ); await axios.post('/api/v1/settings/notifications/email/test', { enabled: true, types: values.types, options: { emailFrom: values.emailFrom, smtpHost: values.smtpHost, smtpPort: Number(values.smtpPort), secure: values.secure, authUser: values.authUser, authPass: values.authPass, senderName: values.senderName, pgpPrivateKey: values.pgpPrivateKey, pgpPassword: values.pgpPassword, }, }); if (toastId) { removeToast(toastId); } addToast(intl.formatMessage(messages.toastEmailTestSuccess), { autoDismiss: true, appearance: 'success', }); } catch (e) { if (toastId) { removeToast(toastId); } addToast(intl.formatMessage(messages.toastEmailTestFailed), { autoDismiss: true, appearance: 'error', }); } finally { setIsTesting(false); } }; return ( <>

{intl.formatMessage( messages.emailNotificationTypesAlertDescription, { strong: function strong(msg) { return ( {msg} ); }, } )}

{intl.formatMessage( messages.emailNotificationTypesAlertDescriptionPt2, { strong: function strong(msg) { return ( {msg} ); }, } )}

} type="info" />
{errors.emailFrom && touched.emailFrom && (
{errors.emailFrom}
)}
{errors.smtpHost && touched.smtpHost && (
{errors.smtpHost}
)}
{errors.smtpPort && touched.smtpPort && (
{errors.smtpPort}
)}
{errors.pgpPrivateKey && touched.pgpPrivateKey && (
{errors.pgpPrivateKey}
)}
{errors.pgpPassword && touched.pgpPassword && (
{errors.pgpPassword}
)}
setFieldValue('types', newTypes)} />
); }}
); }; export default NotificationsEmail;