From 3fc090e1fc1b6a45eca6a109538ee25756658a38 Mon Sep 17 00:00:00 2001 From: sct Date: Thu, 29 Dec 2022 22:02:22 +0900 Subject: [PATCH] fix: adding new checks for plex connection/disconnection in user settings --- server/routes/auth.ts | 4 + src/components/Common/Tooltip/index.tsx | 9 ++ src/components/PlexLoginButton/index.tsx | 4 +- .../UserGeneralSettings/index.tsx | 148 ++++++++++++------ src/pages/_app.tsx | 2 +- 5 files changed, 116 insertions(+), 51 deletions(-) diff --git a/server/routes/auth.ts b/server/routes/auth.ts index 0f59973e0..c1de7f0ee 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -198,6 +198,10 @@ authRoutes.get('/plex/unlink', isAuthenticated(), async (req, res, next) => { const user = await userRepository.findOneByOrFail({ id: req.user.id }); + if (!user.isLocalUser) { + throw new Error('User must have a local password set to unlink Plex.'); + } + user.plexId = null; user.plexToken = null; user.avatar = gravatarUrl(user.email, { default: 'mm', size: 200 }); diff --git a/src/components/Common/Tooltip/index.tsx b/src/components/Common/Tooltip/index.tsx index e8574699e..9901afe4d 100644 --- a/src/components/Common/Tooltip/index.tsx +++ b/src/components/Common/Tooltip/index.tsx @@ -8,6 +8,10 @@ type TooltipProps = { children: React.ReactElement; tooltipConfig?: Partial; className?: string; + /** + * When true, the tooltip will not be shown + */ + disabled?: boolean; }; const Tooltip = ({ @@ -15,6 +19,7 @@ const Tooltip = ({ content, tooltipConfig, className, + disabled, }: TooltipProps) => { const { getTooltipProps, setTooltipRef, setTriggerRef, visible } = usePopperTooltip({ @@ -24,6 +29,10 @@ const Tooltip = ({ ...tooltipConfig, }); + if (disabled) { + return children; + } + const tooltipStyle = [ 'z-50 text-sm absolute font-normal bg-gray-800 px-2 py-1 rounded border border-gray-600 shadow text-gray-100', ]; diff --git a/src/components/PlexLoginButton/index.tsx b/src/components/PlexLoginButton/index.tsx index 1853e0237..b6f506e5d 100644 --- a/src/components/PlexLoginButton/index.tsx +++ b/src/components/PlexLoginButton/index.tsx @@ -21,6 +21,7 @@ type PlexLoginButtonProps = Pick< onError?: (message: string) => void; textOverride?: string; svgIcon?: React.ReactNode; + disabled?: boolean; }; const PlexLoginButton = ({ @@ -31,6 +32,7 @@ const PlexLoginButton = ({ buttonType = 'plex', buttonSize, svgIcon, + disabled, }: PlexLoginButtonProps) => { const intl = useIntl(); const [loading, setLoading] = useState(false); @@ -56,7 +58,7 @@ const PlexLoginButton = ({ plexOAuth.preparePopup(); setTimeout(() => getPlexLogin(), 1500); }} - disabled={loading || isProcessing} + disabled={loading || isProcessing || disabled} buttonType={buttonType} buttonSize={buttonSize} > diff --git a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx index 2506fb608..90e66ef41 100644 --- a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx +++ b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx @@ -2,6 +2,7 @@ import PlexLogo from '@app/assets/services/plex.svg'; import Button from '@app/components/Common/Button'; import LoadingSpinner from '@app/components/Common/LoadingSpinner'; import PageTitle from '@app/components/Common/PageTitle'; +import Tooltip from '@app/components/Common/Tooltip'; import LanguageSelector from '@app/components/LanguageSelector'; import QuotaSelector from '@app/components/QuotaSelector'; import RegionSelector from '@app/components/RegionSelector'; @@ -61,6 +62,16 @@ const messages = defineMessages({ plexwatchlistsyncseries: 'Auto-Request Series', plexwatchlistsyncseriestip: 'Automatically request series on your Plex Watchlist', + noconnectedavailable: 'No connected services available.', + onlyloggedinuseredit: + 'Only the logged in user can edit their own connected accounts.', + connectplexaccount: 'Connect Plex Account', + refreshedtoken: 'Refreshed Plex Token.', + refreshtoken: 'Refresh Token', + mustsetpasswordplex: 'You must set a password before disconnecting Plex.', + disconnectPlex: 'Disconnect Plex', + plexdisconnectedsuccess: 'Plex account disconnected.', + plexdisconnectedfailure: 'Failed to disconnect Plex account.', }); const UserGeneralSettings = () => { @@ -106,13 +117,13 @@ const UserGeneralSettings = () => { try { await axios.get('/api/v1/auth/plex/unlink'); - addToast('Plex account is no longer connected.', { + addToast(intl.formatMessage(messages.plexdisconnectedsuccess), { appearance: 'success', autoDismiss: true, }); revalidateUser(); } catch (e) { - addToast('Failed to disconnect Plex account.', { + addToast(intl.formatMessage(messages.plexdisconnectedfailure), { appearance: 'error', autoDismiss: true, }); @@ -211,55 +222,94 @@ const UserGeneralSettings = () => { -
-
- + {!currentSettings.plexLoginEnabled && user?.id !== 1 && ( +
+
+ {intl.formatMessage(messages.noconnectedavailable)} +
- - {!user?.isPlexUser ? ( - <> -
- { - revalidateUser(); - }} - textOverride="Connect Plex Account" - /> + )} + {(currentSettings.plexLoginEnabled || user?.id === 1) && ( +
+
+ +
+ + {user?.id !== currentUser?.id ? ( +
+ {intl.formatMessage(messages.onlyloggedinuseredit)}
- - ) : ( - <> -
- { - addToast('Refreshed Plex token.', { - appearance: 'success', - autoDismiss: true, - }); - revalidateUser(); - }} - svgIcon={} - textOverride="Refresh Token" - buttonSize="sm" - buttonType="primary" - /> -
- - - )} -
+ ) : ( + <> + {!user?.isPlexUser ? ( + <> +
+ { + revalidateUser(); + }} + textOverride={intl.formatMessage( + messages.connectplexaccount + )} + /> +
+ + ) : ( + <> +
+ { + addToast( + intl.formatMessage(messages.refreshedtoken), + { + appearance: 'success', + autoDismiss: true, + } + ); + revalidateUser(); + }} + svgIcon={} + textOverride={intl.formatMessage( + messages.refreshtoken + )} + buttonSize="sm" + buttonType="primary" + /> +
+ + + + + + + )} + + )} +
+ )}