ghost
Version:
The professional publishing platform
114 lines (98 loc) • 4.89 kB
JavaScript
const _ = require('lodash');
const {ValidationError} = require('@tryghost/errors');
const validator = require('@tryghost/validator');
const tpl = require('@tryghost/tpl');
const AnnouncementBarSettings = require('../../../../../services/announcement-bar-service/AnnouncementBarSettings');
const messages = {
invalidEmailReceived: 'Please send a valid email',
invalidEmailValueReceived: 'Please enter a valid email address.',
invalidEmailTypeReceived: 'Invalid email type received',
invalidAnnouncementVisibilityValueReceived: 'Please enter a valid announcement visibility value',
invalidAnnouncementBackgroundValueReceived: 'Please enter a valid announcement background value'
};
module.exports = {
edit(apiConfig, frame) {
const errors = [];
_.each(frame.data.settings, (setting) => {
// TODO: the below array is INCOMPLETE
// it should include all setting values that have array as a type
const arrayTypeSettings = [
'notifications',
'navigation',
'secondary_navigation',
'announcement_visibility'
];
const emailTypeSettings = [
'members_support_address'
];
if (arrayTypeSettings.includes(setting.key)) {
const typeError = new ValidationError({
message: `Value in ${setting.key} should be an array.`,
property: 'value'
});
// NOTE: The additional check on raw value is here because internal calls to
// settings API use raw unstringified objects (e.g. when adding notifications)
// The conditional can be removed once internals are changed to do the calls properly
// and the JSON.parse should be left as the only valid way to check the value.
if (!_.isArray(setting.value)) {
try {
const value = JSON.parse(setting.value);
if (!_.isArray(value)) {
errors.push(typeError);
}
} catch (err) {
errors.push(typeError);
}
}
}
if (emailTypeSettings.includes(setting.key)) {
const email = setting.value;
if (typeof email !== 'string' || (!validator.isEmail(email) && email !== 'noreply')) {
const typeError = new ValidationError({
message: tpl(messages.invalidEmailValueReceived),
property: setting.key
});
errors.push(typeError);
}
}
if (setting.key === 'announcement_visibility') {
// NOTE: safe to parse because of array validation up top
const visibilityValues = JSON.parse(setting.value);
const validVisibilityValues = [
AnnouncementBarSettings.VisibilityValues.VISITORS,
AnnouncementBarSettings.VisibilityValues.FREE_MEMBERS,
AnnouncementBarSettings.VisibilityValues.PAID_MEMBERS
];
if (visibilityValues.length) {
visibilityValues.forEach((visibilityValue) => {
if (!validVisibilityValues.includes(visibilityValue)) {
const visibilityError = new ValidationError({
message: tpl(messages.invalidAnnouncementVisibilityValueReceived),
property: setting.key
});
errors.push(visibilityError);
}
});
}
}
if (setting.key === 'announcement_background') {
const announcementBackgroundValue = setting.value;
if (!['accent', 'dark', 'light'].includes(announcementBackgroundValue)) {
const visibilityError = new ValidationError({
message: tpl(messages.invalidAnnouncementBackgroundValueReceived),
property: setting.key
});
errors.push(visibilityError);
}
}
});
// Prevent setting icon to the resized one when sending all settings received from browse again in the edit endpoint
const icon = frame.data.settings.find(setting => setting.key === 'icon');
if (icon && icon.value) {
icon.value = icon.value.replace(/\/content\/images\/size\/([^/]+)\//, '/content/images/');
}
if (errors.length) {
return Promise.reject(errors[0]);
}
}
};