2020-04-29 18:44:27 +03:00
|
|
|
const schema = require('../schema').tables;
|
|
|
|
const _ = require('lodash');
|
|
|
|
const validator = require('validator');
|
|
|
|
const moment = require('moment-timezone');
|
|
|
|
const assert = require('assert');
|
|
|
|
const Promise = require('bluebird');
|
2020-05-22 21:22:20 +03:00
|
|
|
const {i18n} = require('../../lib/common');
|
|
|
|
const errors = require('@tryghost/errors');
|
2020-04-29 18:44:27 +03:00
|
|
|
const settingsCache = require('../../services/settings/cache');
|
2020-05-28 13:57:02 +03:00
|
|
|
const urlUtils = require('../../../shared/url-utils');
|
2014-02-19 21:32:23 +04:00
|
|
|
|
2016-03-27 13:19:32 +03:00
|
|
|
function assertString(input) {
|
|
|
|
assert(typeof input === 'string', 'Validator js validates strings only');
|
|
|
|
}
|
|
|
|
|
2017-10-26 13:01:24 +03:00
|
|
|
/**
|
2017-12-12 00:47:46 +03:00
|
|
|
* Counts repeated characters in a string. When 50% or more characters are the same,
|
|
|
|
* we return false and therefore invalidate the string.
|
|
|
|
* @param {String} stringToTest The password string to check.
|
|
|
|
* @return {Boolean}
|
|
|
|
*/
|
2017-10-26 13:01:24 +03:00
|
|
|
function characterOccurance(stringToTest) {
|
2020-04-29 18:44:27 +03:00
|
|
|
const chars = {};
|
|
|
|
let allowedOccurancy;
|
|
|
|
let valid = true;
|
2017-10-26 13:01:24 +03:00
|
|
|
|
|
|
|
stringToTest = _.toString(stringToTest);
|
|
|
|
allowedOccurancy = stringToTest.length / 2;
|
|
|
|
|
|
|
|
// Loop through string and accumulate character counts
|
|
|
|
_.each(stringToTest, function (char) {
|
|
|
|
if (!chars[char]) {
|
|
|
|
chars[char] = 1;
|
|
|
|
} else {
|
|
|
|
chars[char] += 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// check if any of the accumulated chars exceed the allowed occurancy
|
|
|
|
// of 50% of the words' length.
|
|
|
|
_.forIn(chars, function (charCount) {
|
|
|
|
if (charCount >= allowedOccurancy) {
|
|
|
|
valid = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
2016-03-27 13:19:32 +03:00
|
|
|
// extends has been removed in validator >= 5.0.0, need to monkey-patch it back in
|
2017-12-14 03:15:12 +03:00
|
|
|
// @TODO: We modify the global validator dependency here! https://github.com/chriso/validator.js/issues/525#issuecomment-213149570
|
2016-03-27 13:19:32 +03:00
|
|
|
validator.extend = function (name, fn) {
|
|
|
|
validator[name] = function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
const args = Array.prototype.slice.call(arguments);
|
2016-03-27 13:19:32 +03:00
|
|
|
assertString(args[0]);
|
|
|
|
return fn.apply(validator, args);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2014-02-28 10:51:52 +04:00
|
|
|
// Provide a few custom validators
|
2015-06-02 11:52:39 +03:00
|
|
|
validator.extend('empty', function empty(str) {
|
2014-02-28 10:51:52 +04:00
|
|
|
return _.isEmpty(str);
|
|
|
|
});
|
|
|
|
|
2015-06-02 11:52:39 +03:00
|
|
|
validator.extend('notContains', function notContains(str, badString) {
|
2016-06-11 21:23:27 +03:00
|
|
|
return !_.includes(str, badString);
|
2014-02-28 10:51:52 +04:00
|
|
|
});
|
|
|
|
|
2016-07-26 12:23:20 +03:00
|
|
|
validator.extend('isTimezone', function isTimezone(str) {
|
|
|
|
return moment.tz.zone(str) ? true : false;
|
|
|
|
});
|
|
|
|
|
2015-06-02 11:52:39 +03:00
|
|
|
validator.extend('isEmptyOrURL', function isEmptyOrURL(str) {
|
2014-09-10 08:06:24 +04:00
|
|
|
return (_.isEmpty(str) || validator.isURL(str, {require_protocol: false}));
|
2014-07-14 20:32:55 +04:00
|
|
|
});
|
|
|
|
|
2015-09-22 19:38:30 +03:00
|
|
|
validator.extend('isSlug', function isSlug(str) {
|
|
|
|
return validator.matches(str, /^[a-z0-9\-_]+$/);
|
|
|
|
});
|
|
|
|
|
2017-10-26 13:01:24 +03:00
|
|
|
/**
|
2017-12-12 00:47:46 +03:00
|
|
|
* Validation against simple password rules
|
|
|
|
* Returns false when validation fails and true for a valid password
|
|
|
|
* @param {String} password The password string to check.
|
|
|
|
* @param {String} email The users email address to validate agains password.
|
|
|
|
* @param {String} blogTitle Optional blogTitle value, when blog title is not set yet, e. g. in setup process.
|
|
|
|
* @return {Object} example for returned validation Object:
|
|
|
|
* invalid password: `validationResult: {isValid: false, message: 'Sorry, you cannot use an insecure password.'}`
|
|
|
|
* valid password: `validationResult: {isValid: true}`
|
|
|
|
*/
|
2020-06-30 17:41:12 +03:00
|
|
|
function validatePassword(password, email, blogTitle) {
|
2020-04-29 18:44:27 +03:00
|
|
|
const validationResult = {isValid: true};
|
|
|
|
const disallowedPasswords = ['password', 'ghost', 'passw0rd'];
|
|
|
|
let blogUrl = urlUtils.urlFor('home', true);
|
|
|
|
|
|
|
|
const badPasswords = [
|
|
|
|
'1234567890',
|
|
|
|
'qwertyuiop',
|
|
|
|
'qwertzuiop',
|
|
|
|
'asdfghjkl;',
|
|
|
|
'abcdefghij',
|
|
|
|
'0987654321',
|
|
|
|
'1q2w3e4r5t',
|
|
|
|
'12345asdfg'
|
|
|
|
];
|
2017-10-26 13:01:24 +03:00
|
|
|
|
|
|
|
blogTitle = blogTitle ? blogTitle : settingsCache.get('title');
|
|
|
|
blogUrl = blogUrl.replace(/^http(s?):\/\//, '');
|
|
|
|
|
|
|
|
// password must be longer than 10 characters
|
|
|
|
if (!validator.isLength(password, 10)) {
|
|
|
|
validationResult.isValid = false;
|
2020-05-22 21:22:20 +03:00
|
|
|
validationResult.message = i18n.t('errors.models.user.passwordDoesNotComplyLength', {minLength: 10});
|
2017-10-26 13:01:24 +03:00
|
|
|
|
|
|
|
return validationResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
// dissallow password from badPasswords list (e. g. '1234567890')
|
|
|
|
_.each(badPasswords, function (badPassword) {
|
|
|
|
if (badPassword === password) {
|
|
|
|
validationResult.isValid = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// password must not match with users' email
|
|
|
|
if (email && email.toLowerCase() === password.toLowerCase()) {
|
|
|
|
validationResult.isValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// password must not contain the words 'ghost', 'password', or 'passw0rd'
|
|
|
|
_.each(disallowedPasswords, function (disallowedPassword) {
|
|
|
|
if (password.toLowerCase().indexOf(disallowedPassword) >= 0) {
|
|
|
|
validationResult.isValid = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// password must not match with blog title
|
|
|
|
if (blogTitle && blogTitle.toLowerCase() === password.toLowerCase()) {
|
|
|
|
validationResult.isValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// password must not match with blog URL (without protocol, with or without trailing slash)
|
|
|
|
if (blogUrl && (blogUrl.toLowerCase() === password.toLowerCase() || blogUrl.toLowerCase().replace(/\/$/, '') === password.toLowerCase())) {
|
|
|
|
validationResult.isValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// dissallow passwords where 50% or more of characters are the same
|
|
|
|
if (!characterOccurance(password)) {
|
|
|
|
validationResult.isValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic error message for the rules where no dedicated error massage is set
|
|
|
|
if (!validationResult.isValid && !validationResult.message) {
|
2020-05-22 21:22:20 +03:00
|
|
|
validationResult.message = i18n.t('errors.models.user.passwordDoesNotComplySecurity');
|
2017-10-26 13:01:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return validationResult;
|
2020-06-30 17:41:12 +03:00
|
|
|
}
|
2017-10-26 13:01:24 +03:00
|
|
|
|
2018-02-16 02:49:15 +03:00
|
|
|
/**
|
|
|
|
* Validate model against schema.
|
|
|
|
*
|
|
|
|
* ## on model update
|
|
|
|
* - only validate changed fields
|
|
|
|
* - otherwise we could throw errors which the user is out of control
|
|
|
|
* - e.g.
|
|
|
|
* - we add a new field without proper validation, release goes out
|
|
|
|
* - we add proper validation for a single field
|
|
|
|
* - if you call `user.save()` the default fallback in bookshelf is `options.method=update`.
|
|
|
|
* - we set `options.method` explicit for adding resources (because otherwise bookshelf uses `update`)
|
|
|
|
*
|
|
|
|
* ## on model add
|
|
|
|
* - validate everything to catch required fields
|
|
|
|
*/
|
2020-06-30 17:41:12 +03:00
|
|
|
function validateSchema(tableName, model, options) {
|
2018-02-16 02:49:15 +03:00
|
|
|
options = options || {};
|
|
|
|
|
2020-04-29 18:44:27 +03:00
|
|
|
const columns = _.keys(schema[tableName]);
|
|
|
|
let validationErrors = [];
|
2014-02-19 21:32:23 +04:00
|
|
|
|
2015-06-02 11:52:39 +03:00
|
|
|
_.each(columns, function each(columnKey) {
|
2020-04-29 18:44:27 +03:00
|
|
|
let message = ''; // KEEP: Validator.js only validates strings.
|
|
|
|
const strVal = _.toString(model.get(columnKey));
|
2018-02-16 02:49:15 +03:00
|
|
|
|
|
|
|
if (options.method !== 'insert' && !_.has(model.changed, columnKey)) {
|
|
|
|
return;
|
|
|
|
}
|
2014-06-26 08:52:04 +04:00
|
|
|
|
2014-02-19 21:32:23 +04:00
|
|
|
// check nullable
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(schema[tableName][columnKey], 'nullable') &&
|
2018-02-16 02:49:15 +03:00
|
|
|
schema[tableName][columnKey].nullable !== true &&
|
2019-07-05 14:40:43 +03:00
|
|
|
!Object.prototype.hasOwnProperty.call(schema[tableName][columnKey], 'defaultTo')
|
2018-02-16 02:49:15 +03:00
|
|
|
) {
|
2016-03-27 13:19:32 +03:00
|
|
|
if (validator.empty(strVal)) {
|
2020-05-22 21:22:20 +03:00
|
|
|
message = i18n.t('notices.data.validation.index.valueCannotBeBlank', {
|
2017-12-12 00:47:46 +03:00
|
|
|
tableName: tableName,
|
|
|
|
columnKey: columnKey
|
|
|
|
});
|
2020-05-22 21:22:20 +03:00
|
|
|
validationErrors.push(new errors.ValidationError({
|
2017-12-12 00:47:46 +03:00
|
|
|
message: message,
|
|
|
|
context: tableName + '.' + columnKey
|
|
|
|
}));
|
2014-02-28 10:51:52 +04:00
|
|
|
}
|
2014-02-19 21:32:23 +04:00
|
|
|
}
|
2014-06-26 08:52:04 +04:00
|
|
|
|
2016-03-27 13:19:32 +03:00
|
|
|
// validate boolean columns
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(schema[tableName][columnKey], 'type')
|
2017-12-12 00:47:46 +03:00
|
|
|
&& schema[tableName][columnKey].type === 'bool') {
|
2016-03-27 13:19:32 +03:00
|
|
|
if (!(validator.isBoolean(strVal) || validator.empty(strVal))) {
|
2020-05-22 21:22:20 +03:00
|
|
|
message = i18n.t('notices.data.validation.index.valueMustBeBoolean', {
|
2017-12-12 00:47:46 +03:00
|
|
|
tableName: tableName,
|
|
|
|
columnKey: columnKey
|
|
|
|
});
|
2020-05-22 21:22:20 +03:00
|
|
|
validationErrors.push(new errors.ValidationError({
|
2017-12-12 00:47:46 +03:00
|
|
|
message: message,
|
|
|
|
context: tableName + '.' + columnKey
|
|
|
|
}));
|
2016-03-27 13:19:32 +03:00
|
|
|
}
|
2018-06-26 17:00:54 +03:00
|
|
|
|
|
|
|
// CASE: ensure we transform 0|1 to false|true
|
|
|
|
if (!validator.empty(strVal)) {
|
|
|
|
model.set(columnKey, !!model.get(columnKey));
|
|
|
|
}
|
2016-03-27 13:19:32 +03:00
|
|
|
}
|
|
|
|
|
2014-02-19 21:32:23 +04:00
|
|
|
// TODO: check if mandatory values should be enforced
|
2018-02-16 02:49:15 +03:00
|
|
|
if (model.get(columnKey) !== null && model.get(columnKey) !== undefined) {
|
2014-02-19 21:32:23 +04:00
|
|
|
// check length
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(schema[tableName][columnKey], 'maxlength')) {
|
2016-03-27 13:19:32 +03:00
|
|
|
if (!validator.isLength(strVal, 0, schema[tableName][columnKey].maxlength)) {
|
2020-05-22 21:22:20 +03:00
|
|
|
message = i18n.t('notices.data.validation.index.valueExceedsMaxLength',
|
2017-11-01 16:44:54 +03:00
|
|
|
{
|
|
|
|
tableName: tableName,
|
|
|
|
columnKey: columnKey,
|
|
|
|
maxlength: schema[tableName][columnKey].maxlength
|
|
|
|
});
|
2020-05-22 21:22:20 +03:00
|
|
|
validationErrors.push(new errors.ValidationError({
|
2017-11-01 16:44:54 +03:00
|
|
|
message: message,
|
|
|
|
context: tableName + '.' + columnKey
|
|
|
|
}));
|
2014-02-28 10:51:52 +04:00
|
|
|
}
|
2014-02-19 21:32:23 +04:00
|
|
|
}
|
|
|
|
|
2014-09-10 08:06:24 +04:00
|
|
|
// check validations objects
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(schema[tableName][columnKey], 'validations')) {
|
Added more database soft limits (#9225)
refs #8143
Sets soft limits for certain db fields:
- `posts`:
- `title`: 255 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `users`:
- `bio`: 200 chars (current hard limit: 65,535 chars)
- `location`: 150 chars (current hard limit: 65,535 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `tags`:
- `description`: 500 chars (current hard limit: 65,535 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- same error message for isLength validator as for hard limits (more improvements are comming with https://github.com/TryGhost/Ghost/issues/6050)
- added more tests for importer
- added dynamic translation key handling for validators errors (isLength is only supported atm)
2017-11-09 17:22:20 +03:00
|
|
|
validationErrors = validationErrors.concat(validate(strVal, columnKey, schema[tableName][columnKey].validations, tableName));
|
2014-02-19 21:32:23 +04:00
|
|
|
}
|
|
|
|
|
2014-09-10 08:06:24 +04:00
|
|
|
// check type
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(schema[tableName][columnKey], 'type')) {
|
2016-03-27 13:19:32 +03:00
|
|
|
if (schema[tableName][columnKey].type === 'integer' && !validator.isInt(strVal)) {
|
2020-05-22 21:22:20 +03:00
|
|
|
message = i18n.t('notices.data.validation.index.valueIsNotInteger', {
|
2017-11-01 16:44:54 +03:00
|
|
|
tableName: tableName,
|
|
|
|
columnKey: columnKey
|
|
|
|
});
|
2020-05-22 21:22:20 +03:00
|
|
|
validationErrors.push(new errors.ValidationError({
|
2017-11-01 16:44:54 +03:00
|
|
|
message: message,
|
|
|
|
context: tableName + '.' + columnKey
|
|
|
|
}));
|
2014-02-19 21:32:23 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2014-05-05 17:51:21 +04:00
|
|
|
|
2014-05-09 14:11:29 +04:00
|
|
|
if (validationErrors.length !== 0) {
|
2014-08-17 10:17:23 +04:00
|
|
|
return Promise.reject(validationErrors);
|
2014-05-05 17:51:21 +04:00
|
|
|
}
|
2014-06-26 08:52:04 +04:00
|
|
|
|
2014-08-17 10:17:23 +04:00
|
|
|
return Promise.resolve();
|
2020-06-30 17:41:12 +03:00
|
|
|
}
|
2014-02-19 21:32:23 +04:00
|
|
|
|
|
|
|
// Validation for settings
|
|
|
|
// settings are checked against the validation objects
|
|
|
|
// form default-settings.json
|
2020-06-30 17:42:38 +03:00
|
|
|
async function validateSettings(defaultSettings, model) {
|
|
|
|
const setting = model.toJSON();
|
2020-04-29 18:44:27 +03:00
|
|
|
let validationErrors = [];
|
2020-06-30 17:42:38 +03:00
|
|
|
const matchingDefault = defaultSettings[setting.key];
|
2014-02-19 21:32:23 +04:00
|
|
|
|
|
|
|
if (matchingDefault && matchingDefault.validations) {
|
2020-06-30 17:42:38 +03:00
|
|
|
validationErrors = validationErrors.concat(validate(setting.value, setting.key, matchingDefault.validations, 'settings'));
|
2014-05-14 17:30:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (validationErrors.length !== 0) {
|
2014-08-17 10:17:23 +04:00
|
|
|
return Promise.reject(validationErrors);
|
2014-02-19 21:32:23 +04:00
|
|
|
}
|
2014-06-26 08:52:04 +04:00
|
|
|
|
2020-06-30 17:42:38 +03:00
|
|
|
if (setting.key === 'stripe_plans') {
|
|
|
|
const plans = JSON.parse(setting.value);
|
|
|
|
for (const plan of plans) {
|
|
|
|
// We check 100, not 1, because amounts are in fractional units
|
|
|
|
if (plan.amount < 100 && plan.name !== 'Complimentary') {
|
|
|
|
throw new errors.ValidationError({
|
|
|
|
message: 'Plans cannot have an amount less than 1'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-17 10:17:23 +04:00
|
|
|
return Promise.resolve();
|
2020-06-30 17:41:12 +03:00
|
|
|
}
|
2014-02-19 21:32:23 +04:00
|
|
|
|
Added more database soft limits (#9225)
refs #8143
Sets soft limits for certain db fields:
- `posts`:
- `title`: 255 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `users`:
- `bio`: 200 chars (current hard limit: 65,535 chars)
- `location`: 150 chars (current hard limit: 65,535 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `tags`:
- `description`: 500 chars (current hard limit: 65,535 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- same error message for isLength validator as for hard limits (more improvements are comming with https://github.com/TryGhost/Ghost/issues/6050)
- added more tests for importer
- added dynamic translation key handling for validators errors (isLength is only supported atm)
2017-11-09 17:22:20 +03:00
|
|
|
/**
|
|
|
|
* Validate keys using the validator module.
|
|
|
|
* Each validation's key is a method name and its value is an array of options
|
|
|
|
* eg:
|
|
|
|
* validations: { isURL: true, isLength: [20, 40] }
|
|
|
|
* will validate that a values's length is a URL between 20 and 40 chars.
|
|
|
|
*
|
|
|
|
* If you pass a boolean as the value, it will specify the "good" result. By default
|
|
|
|
* the "good" result is assumed to be true.
|
|
|
|
* eg:
|
|
|
|
* validations: { isNull: false } // means the "good" result would
|
|
|
|
* // fail the `isNull` check, so
|
|
|
|
* // not null.
|
|
|
|
*
|
|
|
|
* available validators: https://github.com/chriso/validator.js#validators
|
|
|
|
* @param {String} value the value to validate.
|
|
|
|
* @param {String} key the db column key of the value to validate.
|
|
|
|
* @param {Object} validations the validations object as described above.
|
|
|
|
* @param {String} tableName (optional) the db table of the value to validate, used for error message.
|
|
|
|
* @return {Array} returns an Array including the found validation errors (empty if none found);
|
|
|
|
*/
|
2020-06-30 17:41:12 +03:00
|
|
|
function validate(value, key, validations, tableName) {
|
2020-04-29 18:44:27 +03:00
|
|
|
const validationErrors = [];
|
|
|
|
let translation;
|
2016-06-03 11:06:18 +03:00
|
|
|
value = _.toString(value);
|
2014-06-26 08:52:04 +04:00
|
|
|
|
2015-06-02 11:52:39 +03:00
|
|
|
_.each(validations, function each(validationOptions, validationName) {
|
2020-04-29 18:44:27 +03:00
|
|
|
let goodResult = true;
|
2014-02-19 21:32:23 +04:00
|
|
|
|
2014-02-28 10:51:52 +04:00
|
|
|
if (_.isBoolean(validationOptions)) {
|
|
|
|
goodResult = validationOptions;
|
|
|
|
validationOptions = [];
|
|
|
|
} else if (!_.isArray(validationOptions)) {
|
2014-02-19 21:32:23 +04:00
|
|
|
validationOptions = [validationOptions];
|
|
|
|
}
|
2014-02-28 10:51:52 +04:00
|
|
|
|
|
|
|
validationOptions.unshift(value);
|
|
|
|
|
|
|
|
// equivalent of validator.isSomething(option1, option2)
|
|
|
|
if (validator[validationName].apply(validator, validationOptions) !== goodResult) {
|
Added more database soft limits (#9225)
refs #8143
Sets soft limits for certain db fields:
- `posts`:
- `title`: 255 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `users`:
- `bio`: 200 chars (current hard limit: 65,535 chars)
- `location`: 150 chars (current hard limit: 65,535 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `tags`:
- `description`: 500 chars (current hard limit: 65,535 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- same error message for isLength validator as for hard limits (more improvements are comming with https://github.com/TryGhost/Ghost/issues/6050)
- added more tests for importer
- added dynamic translation key handling for validators errors (isLength is only supported atm)
2017-11-09 17:22:20 +03:00
|
|
|
// CASE: You can define specific translations for validators e.g. isLength
|
2020-05-22 21:22:20 +03:00
|
|
|
if (i18n.doesTranslationKeyExist('notices.data.validation.index.validationFailedTypes.' + validationName)) {
|
|
|
|
translation = i18n.t('notices.data.validation.index.validationFailedTypes.' + validationName, _.merge({
|
Added more database soft limits (#9225)
refs #8143
Sets soft limits for certain db fields:
- `posts`:
- `title`: 255 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `users`:
- `bio`: 200 chars (current hard limit: 65,535 chars)
- `location`: 150 chars (current hard limit: 65,535 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `tags`:
- `description`: 500 chars (current hard limit: 65,535 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- same error message for isLength validator as for hard limits (more improvements are comming with https://github.com/TryGhost/Ghost/issues/6050)
- added more tests for importer
- added dynamic translation key handling for validators errors (isLength is only supported atm)
2017-11-09 17:22:20 +03:00
|
|
|
validationName: validationName,
|
|
|
|
key: key,
|
|
|
|
tableName: tableName
|
|
|
|
}, validationOptions[1]));
|
|
|
|
} else {
|
2020-05-22 21:22:20 +03:00
|
|
|
translation = i18n.t('notices.data.validation.index.validationFailed', {
|
2017-12-12 00:47:46 +03:00
|
|
|
validationName: validationName,
|
|
|
|
key: key
|
|
|
|
});
|
Added more database soft limits (#9225)
refs #8143
Sets soft limits for certain db fields:
- `posts`:
- `title`: 255 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `users`:
- `bio`: 200 chars (current hard limit: 65,535 chars)
- `location`: 150 chars (current hard limit: 65,535 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `tags`:
- `description`: 500 chars (current hard limit: 65,535 chars)
- `meta_title`: 300 chars (current hard limit: 2,000 chars)
- `meta_description`: 500 chars (current hard limit: 2,000 chars)
- same error message for isLength validator as for hard limits (more improvements are comming with https://github.com/TryGhost/Ghost/issues/6050)
- added more tests for importer
- added dynamic translation key handling for validators errors (isLength is only supported atm)
2017-11-09 17:22:20 +03:00
|
|
|
}
|
|
|
|
|
2020-05-22 21:22:20 +03:00
|
|
|
validationErrors.push(new errors.ValidationError({
|
2019-09-16 13:51:54 +03:00
|
|
|
message: translation,
|
|
|
|
context: `${tableName}.${key}`
|
2016-10-06 15:27:35 +03:00
|
|
|
}));
|
2014-02-28 10:51:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
validationOptions.shift();
|
2014-02-19 21:32:23 +04:00
|
|
|
}, this);
|
2014-05-05 17:51:21 +04:00
|
|
|
|
2014-05-14 17:30:46 +04:00
|
|
|
return validationErrors;
|
2020-06-30 17:41:12 +03:00
|
|
|
}
|
2014-02-19 21:32:23 +04:00
|
|
|
|
|
|
|
module.exports = {
|
2020-06-30 17:41:12 +03:00
|
|
|
validate,
|
|
|
|
validator,
|
|
|
|
validatePassword,
|
|
|
|
validateSchema,
|
|
|
|
validateSettings
|
2014-02-27 06:44:09 +04:00
|
|
|
};
|