2021-08-12 15:04:37 +02:00
|
|
|
import joi from 'joi';
|
|
|
|
import { Response } from 'express';
|
2021-08-13 10:36:19 +02:00
|
|
|
import { Logger } from '../logger';
|
2022-01-26 13:45:22 +01:00
|
|
|
import BaseError from '../error/base-error';
|
2021-08-12 15:04:37 +02:00
|
|
|
|
|
|
|
export const customJoi = joi.extend((j) => ({
|
|
|
|
type: 'isUrlFriendly',
|
|
|
|
base: j.string(),
|
|
|
|
messages: {
|
|
|
|
'isUrlFriendly.base': '{{#label}} must be URL friendly',
|
|
|
|
},
|
|
|
|
validate(value, helpers) {
|
|
|
|
// Base validation regardless of the rules applied
|
|
|
|
if (encodeURIComponent(value) !== value) {
|
|
|
|
// Generate an error, state and options need to be passed
|
|
|
|
return { value, errors: helpers.error('isUrlFriendly.base') };
|
|
|
|
}
|
|
|
|
return undefined;
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
|
|
|
export const nameType = customJoi.isUrlFriendly().min(1).max(100).required();
|
|
|
|
|
|
|
|
export const handleErrors: (
|
|
|
|
res: Response,
|
|
|
|
logger: Logger,
|
|
|
|
error: Error,
|
|
|
|
) => void = (res, logger, error) => {
|
|
|
|
logger.warn(error.message);
|
2022-06-07 11:49:17 +02:00
|
|
|
// @ts-expect-error
|
2021-08-12 15:04:37 +02:00
|
|
|
// eslint-disable-next-line no-param-reassign
|
|
|
|
error.isJoi = true;
|
2022-01-26 13:45:22 +01:00
|
|
|
|
|
|
|
if (error instanceof BaseError) {
|
|
|
|
return res.status(error.statusCode).json(error).end();
|
|
|
|
}
|
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
switch (error.name) {
|
|
|
|
case 'ValidationError':
|
|
|
|
return res.status(400).json(error).end();
|
|
|
|
case 'BadDataError':
|
|
|
|
return res.status(400).json(error).end();
|
|
|
|
case 'OwaspValidationError':
|
|
|
|
return res.status(400).json(error).end();
|
|
|
|
case 'PasswordUndefinedError':
|
|
|
|
return res.status(400).json(error).end();
|
2021-11-04 21:09:52 +01:00
|
|
|
case 'MinimumOneEnvironmentError':
|
|
|
|
return res.status(400).json(error).end();
|
2021-11-25 14:53:58 +01:00
|
|
|
case 'InvalidTokenError':
|
|
|
|
return res.status(401).json(error).end();
|
|
|
|
case 'NoAccessError':
|
|
|
|
return res.status(403).json(error).end();
|
|
|
|
case 'UsedTokenError':
|
|
|
|
return res.status(403).json(error).end();
|
|
|
|
case 'InvalidOperationError':
|
|
|
|
return res.status(403).json(error).end();
|
|
|
|
case 'IncompatibleProjectError':
|
|
|
|
return res.status(403).json(error).end();
|
|
|
|
case 'OperationDeniedError':
|
|
|
|
return res.status(403).json(error).end();
|
|
|
|
case 'NotFoundError':
|
|
|
|
return res.status(404).json(error).end();
|
|
|
|
case 'NameExistsError':
|
|
|
|
return res.status(409).json(error).end();
|
|
|
|
case 'FeatureHasTagError':
|
|
|
|
return res.status(409).json(error).end();
|
2022-01-13 11:14:17 +01:00
|
|
|
case 'RoleInUseError':
|
|
|
|
return res.status(400).json(error).end();
|
2022-03-03 14:25:14 +01:00
|
|
|
case 'ProjectWithoutOwnerError':
|
|
|
|
return res.status(409).json(error).end();
|
2021-08-12 15:04:37 +02:00
|
|
|
default:
|
|
|
|
logger.error('Server failed executing request', error);
|
|
|
|
return res.status(500).end();
|
|
|
|
}
|
|
|
|
};
|