fix(jellyfinlogin): add proper error message when no admin user exists (#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.
This commit is contained in:
@@ -4,6 +4,7 @@ export enum ApiErrorCode {
|
|||||||
InvalidAuthToken = 'INVALID_AUTH_TOKEN',
|
InvalidAuthToken = 'INVALID_AUTH_TOKEN',
|
||||||
InvalidEmail = 'INVALID_EMAIL',
|
InvalidEmail = 'INVALID_EMAIL',
|
||||||
NotAdmin = 'NOT_ADMIN',
|
NotAdmin = 'NOT_ADMIN',
|
||||||
|
NoAdminUser = 'NO_ADMIN_USER',
|
||||||
SyncErrorGroupedFolders = 'SYNC_ERROR_GROUPED_FOLDERS',
|
SyncErrorGroupedFolders = 'SYNC_ERROR_GROUPED_FOLDERS',
|
||||||
SyncErrorNoLibraries = 'SYNC_ERROR_NO_LIBRARIES',
|
SyncErrorNoLibraries = 'SYNC_ERROR_NO_LIBRARIES',
|
||||||
Unknown = 'UNKNOWN',
|
Unknown = 'UNKNOWN',
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ authRoutes.post('/jellyfin', async (req, res, next) => {
|
|||||||
body.serverType !== MediaServerType.JELLYFIN &&
|
body.serverType !== MediaServerType.JELLYFIN &&
|
||||||
body.serverType !== MediaServerType.EMBY
|
body.serverType !== MediaServerType.EMBY
|
||||||
) {
|
) {
|
||||||
throw new Error('select_server_type');
|
throw new ApiError(500, ApiErrorCode.NoAdminUser);
|
||||||
}
|
}
|
||||||
settings.main.mediaServerType = body.serverType;
|
settings.main.mediaServerType = body.serverType;
|
||||||
|
|
||||||
@@ -533,6 +533,22 @@ authRoutes.post('/jellyfin', async (req, res, next) => {
|
|||||||
message: e.errorCode,
|
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:
|
default:
|
||||||
logger.error(e.message, { label: 'Auth' });
|
logger.error(e.message, { label: 'Auth' });
|
||||||
return next({
|
return next({
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const messages = defineMessages('components.Login', {
|
|||||||
validationUrlBaseTrailingSlash: 'URL base must not end in a trailing slash',
|
validationUrlBaseTrailingSlash: 'URL base must not end in a trailing slash',
|
||||||
loginerror: 'Something went wrong while trying to sign in.',
|
loginerror: 'Something went wrong while trying to sign in.',
|
||||||
adminerror: 'You must use an admin account 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.',
|
credentialerror: 'The username or password is incorrect.',
|
||||||
invalidurlerror: 'Unable to connect to {mediaServerName} server.',
|
invalidurlerror: 'Unable to connect to {mediaServerName} server.',
|
||||||
signingin: 'Signing in…',
|
signingin: 'Signing in…',
|
||||||
@@ -157,6 +158,9 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
|
|||||||
case ApiErrorCode.NotAdmin:
|
case ApiErrorCode.NotAdmin:
|
||||||
errorMessage = messages.adminerror;
|
errorMessage = messages.adminerror;
|
||||||
break;
|
break;
|
||||||
|
case ApiErrorCode.NoAdminUser:
|
||||||
|
errorMessage = messages.noadminerror;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
errorMessage = messages.loginerror;
|
errorMessage = messages.loginerror;
|
||||||
break;
|
break;
|
||||||
@@ -388,14 +392,35 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
|
|||||||
email: values.username,
|
email: values.username,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
if (!res.ok) throw new Error();
|
if (!res.ok) throw new Error(res.statusText, { cause: res });
|
||||||
} catch (e) {
|
} 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(
|
toasts.addToast(
|
||||||
intl.formatMessage(
|
intl.formatMessage(errorMessage, mediaServerFormatValues),
|
||||||
e.message == 'Request failed with status code 401'
|
|
||||||
? messages.credentialerror
|
|
||||||
: messages.loginerror
|
|
||||||
),
|
|
||||||
{
|
{
|
||||||
autoDismiss: true,
|
autoDismiss: true,
|
||||||
appearance: 'error',
|
appearance: 'error',
|
||||||
|
|||||||
Reference in New Issue
Block a user