From 010df62776191fe4c195e590df338f8d8523f55b Mon Sep 17 00:00:00 2001 From: Danish Humair Date: Sat, 30 Mar 2024 05:53:14 +0500 Subject: [PATCH] feat: check if first jellyfin user is admin (#635) * feat: merge check if first jellyfin user is admin re #610 * refactor(i18n): extract admin error message into en locale --------- Co-authored-by: fallenbagel <98979876+Fallenbagel@users.noreply.github.com> --- server/api/jellyfin.ts | 3 +++ server/routes/auth.ts | 10 ++++++++++ src/components/Login/JellyfinLogin.tsx | 3 +++ src/i18n/locale/en.json | 1 + 4 files changed, 17 insertions(+) diff --git a/server/api/jellyfin.ts b/server/api/jellyfin.ts index 9f7309654..768398a06 100644 --- a/server/api/jellyfin.ts +++ b/server/api/jellyfin.ts @@ -9,6 +9,9 @@ export interface JellyfinUserResponse { ServerId: string; ServerName: string; Id: string; + Policy: { + IsAdministrator: boolean; + }; PrimaryImageTag?: string; } diff --git a/server/routes/auth.ts b/server/routes/auth.ts index 9ec9ff990..c20b4a5f6 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -276,6 +276,11 @@ authRoutes.post('/jellyfin', async (req, res, next) => { }); if (!user && !(await userRepository.count())) { + // Check if user is admin on jellyfin + if (account.User.Policy.IsAdministrator === false) { + throw new Error('not_admin'); + } + logger.info( 'Sign-in attempt from Jellyfin user with access to the media server; creating initial admin user for Overseerr', { @@ -423,6 +428,11 @@ authRoutes.post('/jellyfin', async (req, res, next) => { status: 401, message: 'Unauthorized', }); + } else if (e.message === 'not_admin') { + return next({ + status: 403, + message: 'CREDENTIAL_ERROR_NOT_ADMIN', + }); } else if (e.message === 'add_email') { return next({ status: 406, diff --git a/src/components/Login/JellyfinLogin.tsx b/src/components/Login/JellyfinLogin.tsx index 594a6ff66..e5c01d6ef 100644 --- a/src/components/Login/JellyfinLogin.tsx +++ b/src/components/Login/JellyfinLogin.tsx @@ -24,6 +24,7 @@ const messages = defineMessages({ validationusernamerequired: 'Username required', validationpasswordrequired: 'Password required', loginerror: 'Something went wrong while trying to sign in.', + adminerror: 'You must use an admin account to sign in.', credentialerror: 'The username or password is incorrect.', signingin: 'Signing in…', signin: 'Sign In', @@ -94,6 +95,8 @@ const JellyfinLogin: React.FC = ({ intl.formatMessage( e.message == 'Request failed with status code 401' ? messages.credentialerror + : e.message == 'Request failed with status code 403' + ? messages.adminerror : messages.loginerror ), { diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index 71126cc2d..257ac2220 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -220,6 +220,7 @@ "components.Layout.VersionStatus.streamdevelop": "Overseerr Develop", "components.Layout.VersionStatus.streamstable": "Overseerr Stable", "components.Login.credentialerror": "The username or password is incorrect.", + "components.Login.adminerror": "You must use an admin account to sign in.", "components.Login.description": "Since this is your first time logging into {applicationName}, you are required to add a valid email address.", "components.Login.email": "Email Address", "components.Login.emailtooltip": "Address does not need to be associated with your {mediaServerName} instance.",