diff --git a/server/routes/user/usersettings.ts b/server/routes/user/usersettings.ts index 1b211b7c..3b246005 100644 --- a/server/routes/user/usersettings.ts +++ b/server/routes/user/usersettings.ts @@ -369,6 +369,28 @@ userSettingsRoutes.delete<{ id: string }>( return next({ status: 404, message: 'User not found.' }); } + if (user.id === 1) { + return next({ + status: 400, + message: + 'Cannot unlink media server accounts for the primary administrator.', + }); + } + + const hasPassword = !!( + await userRepository.findOne({ + where: { id: user.id }, + select: ['id', 'password'], + }) + )?.password; + + if (!user.email || !hasPassword) { + return next({ + status: 400, + message: 'User does not have a local email or password set.', + }); + } + user.userType = UserType.LOCAL; user.plexId = null; user.plexUsername = null; @@ -489,6 +511,28 @@ userSettingsRoutes.delete<{ id: string }>( return next({ status: 404, message: 'User not found.' }); } + if (user.id === 1) { + return next({ + status: 400, + message: + 'Cannot unlink media server accounts for the primary administrator.', + }); + } + + const hasPassword = !!( + await userRepository.findOne({ + where: { id: user.id }, + select: ['id', 'password'], + }) + )?.password; + + if (!user.email || !hasPassword) { + return next({ + status: 400, + message: 'User does not have a local email or password set.', + }); + } + user.userType = UserType.LOCAL; user.jellyfinUserId = null; user.jellyfinUsername = null; diff --git a/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx b/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx index 8b7cb03b..9754a1ec 100644 --- a/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx +++ b/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx @@ -15,6 +15,7 @@ import { MediaServerType } from '@server/constants/server'; import { useRouter } from 'next/router'; import { useState } from 'react'; import { useIntl } from 'react-intl'; +import useSWR from 'swr'; import LinkJellyfinModal from './LinkJellyfinModal'; const messages = defineMessages( @@ -56,6 +57,9 @@ const UserLinkedAccountsSettings = () => { hasPermission, revalidate: revalidateUser, } = useUser({ id: Number(router.query.userId) }); + const { data: passwordInfo } = useSWR<{ hasPassword: boolean }>( + user ? `/api/v1/user/${user?.id}/settings/password` : null + ); const [showJellyfinModal, setShowJellyfinModal] = useState(false); const [error, setError] = useState(null); @@ -149,6 +153,8 @@ const UserLinkedAccountsSettings = () => { ); } + const enableMediaServerUnlink = user?.id !== 1 && passwordInfo?.hasPassword; + return ( <> { )} - {error && ( - - {error} - - )} + {error && } {accounts.length ? (
    {accounts.map((acct, i) => ( @@ -209,17 +211,19 @@ const UserLinkedAccountsSettings = () => {
    - { - deleteRequest( - acct.type == LinkedAccountType.Plex ? 'plex' : 'jellyfin' - ); - }} - confirmText={intl.formatMessage(globalMessages.areyousure)} - > - - {intl.formatMessage(globalMessages.delete)} - + {enableMediaServerUnlink && ( + { + deleteRequest( + acct.type == LinkedAccountType.Plex ? 'plex' : 'jellyfin' + ); + }} + confirmText={intl.formatMessage(globalMessages.areyousure)} + > + + {intl.formatMessage(globalMessages.delete)} + + )} ))}