mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 06:37:23 +01:00
* add InvalidCredentialsError with language-agnostic code and update backend & web logout logic * error.code in API error responses Updated the error handler to serialize responseErr.code as the JSON error field, falling back to responseErr.name when no code is set. * fix(lint): whitespace and missing def * fix(lint): missed one * add InvalidCredentialsError case for bad token Add test verifying that auth middleware throws InvalidCredentialsError with code "invalid_credentials" and correct translated message when the API token is invalid. * fix(test): user fields implicitly required --------- Co-authored-by: Kalista Payne <sabrecat@gmail.com>
144 lines
3.7 KiB
JavaScript
144 lines
3.7 KiB
JavaScript
import common from '../../common'; // eslint-disable-line max-classes-per-file
|
||
|
||
export const { CustomError } = common.errors;
|
||
|
||
/**
|
||
* @apiDefine NotAuthorized
|
||
* @apiError NotAuthorized The client is not authorized to make this request.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 401 Unauthorized
|
||
* {
|
||
* "error": "NotAuthorized",
|
||
* "message": "Not authorized."
|
||
* }
|
||
*/
|
||
export const { NotAuthorized } = common.errors;
|
||
|
||
/**
|
||
* @apiDefine BadRequest
|
||
* @apiError BadRequest The request wasn't formatted correctly.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 400 Bad Request
|
||
* {
|
||
* "error": "BadRequest",
|
||
* "message": "Bad request."
|
||
* }
|
||
*/
|
||
export const { BadRequest } = common.errors;
|
||
|
||
/**
|
||
* @apiDefine NotFound
|
||
* @apiError NotFound The requested resource was not found.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 404 Not Found
|
||
* {
|
||
* "error": "NotFound",
|
||
* "message": "Not found."
|
||
* }
|
||
*/
|
||
export const { NotFound } = common.errors;
|
||
|
||
/**
|
||
* @apiDefine Forbidden
|
||
* @apiError Forbidden The requested resource was not found.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 403 Forbidden
|
||
* {
|
||
* "error": "Forbidden",
|
||
* "message": "Access forbidden."
|
||
* }
|
||
*/
|
||
export const { Forbidden } = common.errors;
|
||
|
||
/**
|
||
* @apiDefine TooManyRequests
|
||
* @apiError TooManyRequests The client made too many requests to the API and was rate limited.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 429 TooManyRequests
|
||
* {
|
||
* "error": "TooManyRequests",
|
||
* "message": "Access forbidden."
|
||
* }
|
||
*/
|
||
export const { TooManyRequests } = common.errors;
|
||
|
||
/**
|
||
* @apiDefine RequestTimeout
|
||
* @apiError RequestTimeout The request took too long to complete.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 408 RequestTimeout
|
||
* {
|
||
* "error": "RequestTimeout",
|
||
* "message": "Access forbidden."
|
||
* }
|
||
*/
|
||
export const { RequestTimeout } = common.errors;
|
||
|
||
/**
|
||
* @apiDefine NotificationNotFound
|
||
* @apiError NotificationNotFound The notification was not found.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 404 Not Found
|
||
* {
|
||
* "error": "NotificationNotFound",
|
||
* "message": "Notification not found."
|
||
* }
|
||
*/
|
||
export class NotificationNotFound extends NotFound {
|
||
constructor (language) {
|
||
super(common.i18n.t('messageNotificationNotFound', language));
|
||
this.name = this.constructor.name;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @apiDefine InternalServerError
|
||
* @apiError InternalServerError An unexpected error occurred.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 500 Internal Server Error
|
||
* {
|
||
* "error": "InternalServerError",
|
||
* "message": "An unexpected error occurred."
|
||
* }
|
||
*/
|
||
export class InternalServerError extends CustomError {
|
||
constructor (customMessage) {
|
||
super();
|
||
this.name = this.constructor.name;
|
||
this.httpCode = 500;
|
||
this.message = customMessage || 'An unexpected error occurred.';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @apiDefine InvalidCredentials
|
||
* @apiError InvalidCredentials The user’s credentials are no longer valid.
|
||
*
|
||
* @apiNote
|
||
* The 'invalid_credentials' error code is language-agnostic:
|
||
* clients should use this code (regardless of locale or translated message)
|
||
* to unambiguously trigger a user logout.
|
||
*
|
||
* @apiErrorExample Error-Response:
|
||
* HTTP/1.1 401 Unauthorized
|
||
* {
|
||
* "error": "invalid_credentials",
|
||
* "message": "There is no account that uses those credentials."
|
||
* }
|
||
*/
|
||
export class InvalidCredentialsError extends NotAuthorized {
|
||
constructor (message) {
|
||
super(message);
|
||
this.name = this.constructor.name;
|
||
this.code = 'invalid_credentials';
|
||
}
|
||
}
|