mirror of
https://github.com/Unleash/unleash.git
synced 2024-10-18 20:09:08 +02:00
5cdb3f665a
* task: Ban changes to variants through feature After adding the new `/variants` endpoint for features we now have a way to access control adding/modifying variants, so the /:featureName endpoint should no longer allow editing/adding variants. This removes variants as a known field from the featureMetadata schema and tells joi to stripUnknown, thus making sure we never include variants in the initial creation or future update calls. For the old features v1 API we allow it to declare that it has already validated the data coming with its own schema, so we should use the data we get from it. Thus keeping the old v1 functionality intact Co-authored-by: Simon Hornby <simon@getunleash.ai>
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import joi from 'joi';
|
|
import { Response } from 'express';
|
|
import { Logger } from '../logger';
|
|
|
|
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);
|
|
// @ts-ignore
|
|
// eslint-disable-next-line no-param-reassign
|
|
error.isJoi = true;
|
|
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();
|
|
case 'MinimumOneEnvironmentError':
|
|
return res.status(400).json(error).end();
|
|
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();
|
|
default:
|
|
logger.error('Server failed executing request', error);
|
|
return res.status(500).end();
|
|
}
|
|
};
|