Skip to content

Commit

Permalink
fix(jellyfinlogin): add proper error message when no admin user exists (
Browse files Browse the repository at this point in the history
#1216)

This PR adds an error message when the database has no admin user and Jellyseerr has already been
set up (i.e. settings.json is filled in), instead of having a generic error message.
  • Loading branch information
gauthier-th authored Jan 2, 2025
1 parent d67ec57 commit ac90802
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
1 change: 1 addition & 0 deletions server/constants/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum ApiErrorCode {
InvalidAuthToken = 'INVALID_AUTH_TOKEN',
InvalidEmail = 'INVALID_EMAIL',
NotAdmin = 'NOT_ADMIN',
NoAdminUser = 'NO_ADMIN_USER',
SyncErrorGroupedFolders = 'SYNC_ERROR_GROUPED_FOLDERS',
SyncErrorNoLibraries = 'SYNC_ERROR_NO_LIBRARIES',
Unknown = 'UNKNOWN',
Expand Down
18 changes: 17 additions & 1 deletion server/routes/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ authRoutes.post('/jellyfin', async (req, res, next) => {
body.serverType !== MediaServerType.JELLYFIN &&
body.serverType !== MediaServerType.EMBY
) {
throw new Error('select_server_type');
throw new ApiError(500, ApiErrorCode.NoAdminUser);
}
settings.main.mediaServerType = body.serverType;

Expand Down Expand Up @@ -533,6 +533,22 @@ authRoutes.post('/jellyfin', async (req, res, next) => {
message: e.errorCode,
});

case ApiErrorCode.NoAdminUser:
logger.warn(
'Failed login attempt from user without admin permissions and no admin user exists',
{
label: 'Auth',
account: {
ip: req.ip,
email: body.username,
},
}
);
return next({
status: e.statusCode,
message: e.errorCode,
});

default:
logger.error(e.message, { label: 'Auth' });
return next({
Expand Down
37 changes: 31 additions & 6 deletions src/components/Login/JellyfinLogin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const messages = defineMessages('components.Login', {
validationUrlBaseTrailingSlash: 'URL base must not end in a trailing slash',
loginerror: 'Something went wrong while trying to sign in.',
adminerror: 'You must use an admin account to sign in.',
noadminerror: 'No admin user found on the server.',
credentialerror: 'The username or password is incorrect.',
invalidurlerror: 'Unable to connect to {mediaServerName} server.',
signingin: 'Signing in…',
Expand Down Expand Up @@ -157,6 +158,9 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
case ApiErrorCode.NotAdmin:
errorMessage = messages.adminerror;
break;
case ApiErrorCode.NoAdminUser:
errorMessage = messages.noadminerror;
break;
default:
errorMessage = messages.loginerror;
break;
Expand Down Expand Up @@ -388,14 +392,35 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
email: values.username,
}),
});
if (!res.ok) throw new Error();
if (!res.ok) throw new Error(res.statusText, { cause: res });
} catch (e) {
let errorData;
try {
errorData = await e.cause?.text();
errorData = JSON.parse(errorData);
} catch {
/* empty */
}
let errorMessage = null;
switch (errorData?.message) {
case ApiErrorCode.InvalidUrl:
errorMessage = messages.invalidurlerror;
break;
case ApiErrorCode.InvalidCredentials:
errorMessage = messages.credentialerror;
break;
case ApiErrorCode.NotAdmin:
errorMessage = messages.adminerror;
break;
case ApiErrorCode.NoAdminUser:
errorMessage = messages.noadminerror;
break;
default:
errorMessage = messages.loginerror;
break;
}
toasts.addToast(
intl.formatMessage(
e.message == 'Request failed with status code 401'
? messages.credentialerror
: messages.loginerror
),
intl.formatMessage(errorMessage, mediaServerFormatValues),
{
autoDismiss: true,
appearance: 'error',
Expand Down

0 comments on commit ac90802

Please sign in to comment.