diff --git a/src/lib/error/bad-data-error.ts b/src/lib/error/bad-data-error.ts index 300e2dce520..715aad9c4cd 100644 --- a/src/lib/error/bad-data-error.ts +++ b/src/lib/error/bad-data-error.ts @@ -19,5 +19,5 @@ class BadDataError extends Error { }; } } + export default BadDataError; -module.exports = BadDataError; diff --git a/src/lib/error/base-error.ts b/src/lib/error/base-error.ts new file mode 100644 index 00000000000..73c6e311441 --- /dev/null +++ b/src/lib/error/base-error.ts @@ -0,0 +1,26 @@ +class BaseError extends Error { + readonly statusCode: number; + + constructor(message: string, statusCode: number, name: string) { + super(); + + this.name = name; + this.message = message; + this.statusCode = statusCode; + Error.captureStackTrace(this, this.constructor); + } + + toJSON(): object { + return { + isJoi: true, + name: this.constructor.name, + details: [ + { + message: this.message, + }, + ], + }; + } +} + +export default BaseError; diff --git a/src/lib/error/disabled-error.ts b/src/lib/error/disabled-error.ts new file mode 100644 index 00000000000..0f4fc768a09 --- /dev/null +++ b/src/lib/error/disabled-error.ts @@ -0,0 +1,10 @@ +import BaseError from './base-error'; + +class DisabledError extends BaseError { + constructor(message: string) { + super(message, 422, 'DisabledError'); + Error.captureStackTrace(this, this.constructor); + } +} + +export default DisabledError; diff --git a/src/lib/error/password-mismatch.ts b/src/lib/error/password-mismatch.ts new file mode 100644 index 00000000000..9be29eaf97b --- /dev/null +++ b/src/lib/error/password-mismatch.ts @@ -0,0 +1,10 @@ +import BaseError from './base-error'; + +class PasswordMismatch extends BaseError { + constructor(message: string = 'Wrong password, try again.') { + super(message, 401, 'PasswordMismatch'); + Error.captureStackTrace(this, this.constructor); + } +} + +export default PasswordMismatch; diff --git a/src/lib/routes/auth/reset-password-controller.ts b/src/lib/routes/auth/reset-password-controller.ts index ae2f72d0c8b..263525902f4 100644 --- a/src/lib/routes/auth/reset-password-controller.ts +++ b/src/lib/routes/auth/reset-password-controller.ts @@ -79,4 +79,3 @@ class ResetPasswordController extends Controller { } export default ResetPasswordController; -module.exports = ResetPasswordController; diff --git a/src/lib/routes/auth/simple-password-provider.js b/src/lib/routes/auth/simple-password-provider.js index fda12f788e4..de86dc7bb5f 100644 --- a/src/lib/routes/auth/simple-password-provider.js +++ b/src/lib/routes/auth/simple-password-provider.js @@ -18,13 +18,9 @@ class PasswordProvider extends Controller { }); } - try { - const user = await this.userService.loginUser(username, password); - req.session.user = user; - return res.status(200).json(user); - } catch (e) { - return res.status(401).json({ message: e.message }); - } + const user = await this.userService.loginUser(username, password); + req.session.user = user; + return res.status(200).json(user); } } diff --git a/src/lib/routes/util.ts b/src/lib/routes/util.ts index df4ea5de37c..07798cbd208 100644 --- a/src/lib/routes/util.ts +++ b/src/lib/routes/util.ts @@ -1,6 +1,7 @@ import joi from 'joi'; import { Response } from 'express'; import { Logger } from '../logger'; +import BaseError from '../error/base-error'; export const customJoi = joi.extend((j) => ({ type: 'isUrlFriendly', @@ -29,6 +30,11 @@ export const handleErrors: ( // @ts-ignore // eslint-disable-next-line no-param-reassign error.isJoi = true; + + if (error instanceof BaseError) { + return res.status(error.statusCode).json(error).end(); + } + switch (error.name) { case 'ValidationError': return res.status(400).json(error).end(); diff --git a/src/lib/services/user-service.ts b/src/lib/services/user-service.ts index 03d7d86e30f..8226ba9392f 100644 --- a/src/lib/services/user-service.ts +++ b/src/lib/services/user-service.ts @@ -24,6 +24,8 @@ import { RoleName } from '../types/model'; import SettingService from './setting-service'; import { SimpleAuthSettings } from '../server-impl'; import { simpleAuthKey } from '../types/settings/simple-auth-settings'; +import DisabledError from '../error/disabled-error'; +import PasswordMismatch from '../error/password-mismatch'; const systemUser = new User({ id: -1, username: 'system' }); @@ -273,8 +275,8 @@ class UserService { simpleAuthKey, ); - if (settings && settings.disabled) { - throw new Error( + if (settings?.disabled) { + throw new DisabledError( 'Logging in with username/password has been disabled.', ); } @@ -290,7 +292,7 @@ class UserService { await this.store.successfullyLogin(user); return user; } - throw new Error('Wrong password, try again.'); + throw new PasswordMismatch(); } /**