diff --git a/overseerr-api.yml b/overseerr-api.yml index 6d9888af..25e13a0a 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -4427,6 +4427,8 @@ paths: responses: '204': description: Unlinking account succeeded + '400': + description: Unlink request invalid '404': description: User does not exist /user/{userId}/settings/linked-accounts/jellyfin: @@ -4475,6 +4477,8 @@ paths: responses: '204': description: Unlinking account succeeded + '400': + description: Unlink request invalid '404': description: User does not exist /user/{userId}/settings/notifications: diff --git a/server/constants/error.ts b/server/constants/error.ts index 664f02c9..daa02f1a 100644 --- a/server/constants/error.ts +++ b/server/constants/error.ts @@ -7,5 +7,6 @@ export enum ApiErrorCode { NoAdminUser = 'NO_ADMIN_USER', SyncErrorGroupedFolders = 'SYNC_ERROR_GROUPED_FOLDERS', SyncErrorNoLibraries = 'SYNC_ERROR_NO_LIBRARIES', + Unauthorized = 'UNAUTHORIZED', Unknown = 'UNKNOWN', } diff --git a/server/routes/user/usersettings.ts b/server/routes/user/usersettings.ts index 092ce2a4..6bba393f 100644 --- a/server/routes/user/usersettings.ts +++ b/server/routes/user/usersettings.ts @@ -200,9 +200,8 @@ userSettingsRoutes.post< status: e.statusCode, message: e.errorCode, }); - } else { - return next({ status: 500, message: e.message }); } + return next({ status: 500, message: e.message }); } }); @@ -310,16 +309,16 @@ userSettingsRoutes.post< userSettingsRoutes.post<{ authToken: string }>( '/linked-accounts/plex', isOwnProfile(), - async (req, res, next) => { + async (req, res) => { const settings = getSettings(); const userRepository = getRepository(User); if (!req.user) { - return next({ status: 404, message: 'Unauthorized' }); + return res.status(404).json({ code: ApiErrorCode.Unauthorized }); } // Make sure Plex login is enabled if (settings.main.mediaServerType !== MediaServerType.PLEX) { - return res.status(500).json({ error: 'Plex login is disabled' }); + return res.status(500).json({ message: 'Plex login is disabled' }); } // First we need to use this auth token to get the user's email from plex.tv @@ -329,7 +328,7 @@ userSettingsRoutes.post<{ authToken: string }>( // Do not allow linking of an already linked account if (await userRepository.exist({ where: { plexId: account.id } })) { return res.status(422).json({ - error: 'This Plex account is already linked to a Jellyseerr user', + message: 'This Plex account is already linked to a Jellyseerr user', }); } @@ -338,7 +337,7 @@ userSettingsRoutes.post<{ authToken: string }>( // Emails do not match if (user.email !== account.email) { return res.status(422).json({ - error: + message: 'This Plex account is registered under a different email address.', }); } @@ -357,13 +356,13 @@ userSettingsRoutes.post<{ authToken: string }>( userSettingsRoutes.delete<{ id: string }>( '/linked-accounts/plex', isOwnProfileOrAdmin(), - async (req, res, next) => { + async (req, res) => { const settings = getSettings(); const userRepository = getRepository(User); // Make sure Plex login is enabled if (settings.main.mediaServerType !== MediaServerType.PLEX) { - return res.status(500).json({ error: 'Plex login is disabled' }); + return res.status(500).json({ message: 'Plex login is disabled' }); } try { @@ -372,12 +371,11 @@ userSettingsRoutes.delete<{ id: string }>( }); if (!user) { - return next({ status: 404, message: 'User not found.' }); + return res.status(404).json({ message: 'User not found.' }); } if (user.id === 1) { - return next({ - status: 400, + return res.status(400).json({ message: 'Cannot unlink media server accounts for the primary administrator.', }); @@ -391,8 +389,7 @@ userSettingsRoutes.delete<{ id: string }>( )?.password; if (!user.email || !hasPassword) { - return next({ - status: 400, + return res.status(400).json({ message: 'User does not have a local email or password set.', }); } @@ -405,7 +402,7 @@ userSettingsRoutes.delete<{ id: string }>( return res.status(204).send(); } catch (e) { - next({ status: 500, message: e.message }); + return res.status(500).json({ message: e.message }); } } ); @@ -413,19 +410,21 @@ userSettingsRoutes.delete<{ id: string }>( userSettingsRoutes.post<{ username: string; password: string }>( '/linked-accounts/jellyfin', isOwnProfile(), - async (req, res, next) => { + async (req, res) => { const settings = getSettings(); const userRepository = getRepository(User); if (!req.user) { - return next({ status: 401, message: 'Unauthorized' }); + return res.status(401).json({ code: ApiErrorCode.Unauthorized }); } // Make sure jellyfin login is enabled if ( settings.main.mediaServerType !== MediaServerType.JELLYFIN && settings.main.mediaServerType !== MediaServerType.EMBY ) { - return res.status(500).json({ error: 'Jellyfin/Emby login is disabled' }); + return res + .status(500) + .json({ message: 'Jellyfin/Emby login is disabled' }); } // Do not allow linking of an already linked account @@ -435,7 +434,7 @@ userSettingsRoutes.post<{ username: string; password: string }>( }) ) { return res.status(422).json({ - error: 'The specified account is already linked to a Jellyseerr user', + message: 'The specified account is already linked to a Jellyseerr user', }); } @@ -447,7 +446,7 @@ userSettingsRoutes.post<{ username: string; password: string }>( const jellyfinserver = new JellyfinAPI(hostname, undefined, deviceId); const ip = req.ip; - let clientIp; + let clientIp: string | undefined; if (ip) { if (net.isIPv4(ip)) { clientIp = ip; @@ -470,7 +469,8 @@ userSettingsRoutes.post<{ username: string; password: string }>( }) ) { return res.status(422).json({ - error: 'The specified account is already linked to a Jellyseerr user', + message: + 'The specified account is already linked to a Jellyseerr user', }); } @@ -496,12 +496,12 @@ userSettingsRoutes.post<{ username: string; password: string }>( }); if ( e instanceof ApiError && - (e.errorCode == ApiErrorCode.InvalidCredentials || - e.errorCode == ApiErrorCode.NotAdmin) - ) - return next({ status: 401, message: 'Unauthorized' }); + e.errorCode === ApiErrorCode.InvalidCredentials + ) { + return res.status(401).json({ code: e.errorCode }); + } - return next({ status: 500 }); + return res.status(500).send(); } } ); @@ -509,7 +509,7 @@ userSettingsRoutes.post<{ username: string; password: string }>( userSettingsRoutes.delete<{ id: string }>( '/linked-accounts/jellyfin', isOwnProfileOrAdmin(), - async (req, res, next) => { + async (req, res) => { const settings = getSettings(); const userRepository = getRepository(User); @@ -518,7 +518,9 @@ userSettingsRoutes.delete<{ id: string }>( settings.main.mediaServerType !== MediaServerType.JELLYFIN && settings.main.mediaServerType !== MediaServerType.EMBY ) { - return res.status(500).json({ error: 'Jellyfin/Emby login is disabled' }); + return res + .status(500) + .json({ message: 'Jellyfin/Emby login is disabled' }); } try { @@ -527,12 +529,11 @@ userSettingsRoutes.delete<{ id: string }>( }); if (!user) { - return next({ status: 404, message: 'User not found.' }); + return res.status(404).json({ message: 'User not found.' }); } if (user.id === 1) { - return next({ - status: 400, + return res.status(400).json({ message: 'Cannot unlink media server accounts for the primary administrator.', }); @@ -546,8 +547,7 @@ userSettingsRoutes.delete<{ id: string }>( )?.password; if (!user.email || !hasPassword) { - return next({ - status: 400, + return res.status(400).json({ message: 'User does not have a local email or password set.', }); } @@ -561,7 +561,7 @@ userSettingsRoutes.delete<{ id: string }>( return res.status(204).send(); } catch (e) { - next({ status: 500, message: e.message }); + return res.status(500).json({ message: e.message }); } } );