mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Switch to @trghost/validator, remove validator
- Part of the effort to split Ghost down into smaller, decoupled pieces - Moved out our internal validator tooling to a separate library - Replaced all usage of our own tooling and validatorjs directly with @tryghost/validator - Removed the validatorjs dependency and removed the renovate pin - This gives us a consistant, smaller, clearer public API for validations - It will eventually be used on Ghost Admin too - This way we can start getting up to date with validator whilst not increasing build size
This commit is contained in:
parent
97c0c93959
commit
526993965a
29 changed files with 40 additions and 211 deletions
|
@ -1,5 +1,5 @@
|
|||
const _ = require('lodash');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const BaseMapGenerator = require('./base-generator');
|
||||
|
||||
class UserMapGenerator extends BaseMapGenerator {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const Promise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const models = require('../../models');
|
||||
const frontendRouting = require('../../../frontend/services/routing');
|
||||
const frontendSettings = require('../../../frontend/services/settings');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const debug = require('@tryghost/debug')('api:canary:utils:validators:input:invitation');
|
||||
const i18n = require('../../../../../../shared/i18n');
|
||||
const errors = require('@tryghost/errors');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const debug = require('@tryghost/debug')('api:canary:utils:validators:input:passwordreset');
|
||||
const i18n = require('../../../../../../shared/i18n');
|
||||
const errors = require('@tryghost/errors');
|
||||
|
|
|
@ -3,7 +3,7 @@ const _ = require('lodash');
|
|||
const Promise = require('bluebird');
|
||||
const i18n = require('../../../../../shared/i18n');
|
||||
const {BadRequestError, ValidationError} = require('@tryghost/errors');
|
||||
const validator = require('../../../../data/validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
|
||||
const GLOBAL_VALIDATORS = {
|
||||
id: {matches: /^[a-f\d]{24}$|^1$|me/i},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const debug = require('@tryghost/debug')('api:v2:utils:validators:input:invitation');
|
||||
const i18n = require('../../../../../../shared/i18n');
|
||||
const errors = require('@tryghost/errors');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const debug = require('@tryghost/debug')('api:v2:utils:validators:input:passwordreset');
|
||||
const i18n = require('../../../../../../shared/i18n');
|
||||
const errors = require('@tryghost/errors');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const Promise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const models = require('../../models');
|
||||
const frontendRouting = require('../../../frontend/services/routing');
|
||||
const frontendSettings = require('../../../frontend/services/settings');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const debug = require('@tryghost/debug')('api:v3:utils:validators:input:invitation');
|
||||
const i18n = require('../../../../../../shared/i18n');
|
||||
const errors = require('@tryghost/errors');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const debug = require('@tryghost/debug')('api:v3:utils:validators:input:passwordreset');
|
||||
const i18n = require('../../../../../../shared/i18n');
|
||||
const errors = require('@tryghost/errors');
|
||||
|
|
|
@ -3,7 +3,7 @@ const _ = require('lodash');
|
|||
const uuid = require('uuid');
|
||||
const BaseImporter = require('./base');
|
||||
const mobiledocLib = require('../../../../lib/mobiledoc');
|
||||
const validator = require('../../../validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const postsMetaSchema = require('../../../schema').tables.posts_meta;
|
||||
const metaAttrs = _.keys(_.omit(postsMetaSchema, ['id']));
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ const Promise = require('bluebird');
|
|||
|
||||
const tpl = require('@tryghost/tpl');
|
||||
const errors = require('@tryghost/errors');
|
||||
const validator = require('../validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
|
||||
const schema = require('./schema');
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
module.exports = require('./validator');
|
||||
module.exports.validate = require('./validate');
|
|
@ -1,80 +0,0 @@
|
|||
const _ = require('lodash');
|
||||
const validator = require('./validator');
|
||||
|
||||
const tpl = require('@tryghost/tpl');
|
||||
const errors = require('@tryghost/errors');
|
||||
|
||||
const messages = {
|
||||
validationFailed: 'Validation ({validationName}) failed for {key}',
|
||||
validationFailedTypes: {
|
||||
isLength: 'Value in [{tableName}.{key}] exceeds maximum length of {max} characters.'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
*/
|
||||
function validate(value, key, validations, tableName) {
|
||||
const validationErrors = [];
|
||||
let message;
|
||||
value = _.toString(value);
|
||||
|
||||
_.each(validations, (validationOptions, validationName) => {
|
||||
let goodResult = true;
|
||||
|
||||
if (_.isBoolean(validationOptions)) {
|
||||
goodResult = validationOptions;
|
||||
validationOptions = [];
|
||||
} else if (!_.isArray(validationOptions)) {
|
||||
validationOptions = [validationOptions];
|
||||
}
|
||||
|
||||
validationOptions.unshift(value);
|
||||
|
||||
// equivalent of validator.isSomething(option1, option2)
|
||||
if (validator[validationName].apply(validator, validationOptions) !== goodResult) {
|
||||
// CASE: You can define specific messages for validators e.g. isLength
|
||||
if (_.has(messages.validationFailedTypes, validationName)) {
|
||||
message = tpl(messages.validationFailedTypes[validationName], _.merge({
|
||||
validationName: validationName,
|
||||
key: key,
|
||||
tableName: tableName
|
||||
}, validationOptions[1]));
|
||||
} else {
|
||||
message = tpl(messages.validationFailed, {
|
||||
validationName: validationName,
|
||||
key: key
|
||||
});
|
||||
}
|
||||
|
||||
validationErrors.push(new errors.ValidationError({
|
||||
message: message,
|
||||
context: `${tableName}.${key}`
|
||||
}));
|
||||
}
|
||||
|
||||
validationOptions.shift();
|
||||
});
|
||||
|
||||
return validationErrors;
|
||||
}
|
||||
|
||||
module.exports = validate;
|
|
@ -1,48 +0,0 @@
|
|||
const _ = require('lodash');
|
||||
|
||||
const baseValidator = require('validator');
|
||||
const moment = require('moment-timezone');
|
||||
const assert = require('assert');
|
||||
|
||||
const allowedValidators = [
|
||||
'isLength',
|
||||
'isEmpty',
|
||||
'isURL',
|
||||
'isEmail',
|
||||
'isIn',
|
||||
'isUUID',
|
||||
'isBoolean',
|
||||
'isInt',
|
||||
'isLowercase',
|
||||
'equals',
|
||||
'matches'
|
||||
];
|
||||
|
||||
function assertString(input) {
|
||||
assert(typeof input === 'string', 'Validator validates strings only');
|
||||
}
|
||||
|
||||
const validators = {};
|
||||
|
||||
allowedValidators.forEach((name) => {
|
||||
if (_.has(baseValidator, name)) {
|
||||
validators[name] = baseValidator[name];
|
||||
}
|
||||
});
|
||||
|
||||
validators.isTimezone = function isTimezone(str) {
|
||||
assertString(str);
|
||||
return moment.tz.zone(str) ? true : false;
|
||||
};
|
||||
|
||||
validators.isEmptyOrURL = function isEmptyOrURL(str) {
|
||||
assertString(str);
|
||||
return (validators.isEmpty(str) || validators.isURL(str, {require_protocol: false}));
|
||||
};
|
||||
|
||||
validators.isSlug = function isSlug(str) {
|
||||
assertString(str);
|
||||
return validators.matches(str, /^[a-z0-9\-_]+$/);
|
||||
};
|
||||
|
||||
module.exports = validators;
|
|
@ -2,7 +2,7 @@ const request = require('../request');
|
|||
const urlUtils = require('../../../shared/url-utils');
|
||||
const storage = require('../../adapters/storage');
|
||||
const storageUtils = require('../../adapters/storage/utils');
|
||||
const validator = require('../../data/validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const config = require('../../../shared/config');
|
||||
const logging = require('@tryghost/logging');
|
||||
const i18n = require('../../../shared/i18n');
|
||||
|
|
|
@ -2,7 +2,7 @@ const got = require('got');
|
|||
const dnsPromises = require('dns').promises;
|
||||
const errors = require('@tryghost/errors');
|
||||
const config = require('../../shared/config');
|
||||
const validator = require('../data/validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
|
||||
function isPrivateIp(addr) {
|
||||
return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const got = require('got');
|
||||
const _ = require('lodash');
|
||||
const validator = require('../data/validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const errors = require('@tryghost/errors');
|
||||
const ghostVersion = require('./ghost-version');
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const _ = require('lodash');
|
||||
|
||||
const validator = require('../data/validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
|
||||
const tpl = require('@tryghost/tpl');
|
||||
const settingsCache = require('../services/settings/cache');
|
||||
|
|
|
@ -7,7 +7,7 @@ const ObjectID = require('bson-objectid');
|
|||
const ghostBookshelf = require('./base');
|
||||
const i18n = require('../../shared/i18n');
|
||||
const errors = require('@tryghost/errors');
|
||||
const validator = require('../data/validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const urlUtils = require('../../shared/url-utils');
|
||||
const {WRITABLE_KEYS_ALLOWLIST} = require('../services/labs');
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const _ = require('lodash');
|
||||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const ObjectId = require('bson-objectid');
|
||||
const ghostBookshelf = require('./base');
|
||||
const baseUtils = require('./base/utils');
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Handles sending email for Ghost
|
||||
const _ = require('lodash');
|
||||
const Promise = require('bluebird');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
const config = require('../../../shared/config');
|
||||
const errors = require('@tryghost/errors');
|
||||
const i18n = require('../../../shared/i18n');
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
"@tryghost/tpl": "0.1.1",
|
||||
"@tryghost/update-check-service": "0.1.0",
|
||||
"@tryghost/url-utils": "1.1.4",
|
||||
"@tryghost/validator": "0.1.0",
|
||||
"@tryghost/vhost-middleware": "1.0.15",
|
||||
"@tryghost/zip": "1.1.14",
|
||||
"amperize": "0.6.1",
|
||||
|
@ -145,7 +146,6 @@
|
|||
"stoppable": "1.1.0",
|
||||
"tough-cookie": "4.0.0",
|
||||
"uuid": "8.3.2",
|
||||
"validator": "7.2.0",
|
||||
"xml": "1.0.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
"moment",
|
||||
"moment-timezone",
|
||||
"nodemailer",
|
||||
"validator",
|
||||
"simple-dom"
|
||||
],
|
||||
"ignorePaths": ["test"],
|
||||
|
|
|
@ -6,7 +6,7 @@ const moment = require('moment-timezone');
|
|||
const ObjectId = require('bson-objectid');
|
||||
const assert = require('assert');
|
||||
const _ = require('lodash');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
|
||||
// Stuff we are testing
|
||||
const db = require('../../../core/server/data/db');
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
const should = require('should');
|
||||
|
||||
const validator = require('../../../../core/server/data/validator');
|
||||
|
||||
// Validate our customizations
|
||||
describe('Validate', function () {
|
||||
it('should export our required functions', function () {
|
||||
should.exist(validator);
|
||||
|
||||
validator.should.have.properties(
|
||||
['validate']
|
||||
);
|
||||
|
||||
validator.validate.should.be.a.Function();
|
||||
});
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
const should = require('should');
|
||||
|
||||
const validator = require('../../../../core/server/data/validator');
|
||||
|
||||
const validators = ['isLength',
|
||||
'isEmpty',
|
||||
'isURL',
|
||||
'isEmail',
|
||||
'isIn',
|
||||
'isUUID',
|
||||
'isBoolean',
|
||||
'isInt',
|
||||
'isLowercase',
|
||||
'equals',
|
||||
'matches'
|
||||
];
|
||||
|
||||
const custom = ['isTimezone', 'isEmptyOrURL', 'isSlug'];
|
||||
|
||||
describe('Validator', function () {
|
||||
it('should export our required functions', function () {
|
||||
should.exist(validator);
|
||||
|
||||
const allMethods = validators.concat(custom).concat('validate');
|
||||
|
||||
Object.keys(validator).should.eql(allMethods);
|
||||
});
|
||||
|
||||
describe('Custom Validators', function () {
|
||||
it('isEmptyOrUrl filters javascript urls', function () {
|
||||
validator.isEmptyOrURL('javascript:alert(0)').should.be.false();
|
||||
validator.isEmptyOrURL('http://example.com/lol/<script>lalala</script>/').should.be.false();
|
||||
validator.isEmptyOrURL('http://example.com/lol?somequery=<script>lalala</script>').should.be.false();
|
||||
validator.isEmptyOrURL('').should.be.true();
|
||||
validator.isEmptyOrURL('http://localhost:2368').should.be.true();
|
||||
validator.isEmptyOrURL('http://example.com/test/').should.be.true();
|
||||
validator.isEmptyOrURL('http://www.example.com/test/').should.be.true();
|
||||
validator.isEmptyOrURL('http://example.com/foo?somequery=bar').should.be.true();
|
||||
validator.isEmptyOrURL('example.com/test/').should.be.true();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
const should = require('should');
|
||||
const sinon = require('sinon');
|
||||
const validator = require('validator');
|
||||
const validator = require('@tryghost/validator');
|
||||
|
||||
const requestId = require('../../../../../core/server/web/parent/middleware/request-id');
|
||||
|
||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -1015,6 +1015,13 @@
|
|||
c8 "^7.7.2"
|
||||
lodash.template "^4.5.0"
|
||||
|
||||
"@tryghost/tpl@^0.1.2":
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/tpl/-/tpl-0.1.2.tgz#4b6acc97a6ac517baf40585216c8adf888d620f1"
|
||||
integrity sha512-VZyD4v8rNJrJEWUjrAT7YCpEmr+8rXWhQbfmWE199F29pbEpvMPK0MKwF1hTc3b0JkvGOo3lgULJ7KB6TrxvkA==
|
||||
dependencies:
|
||||
lodash.template "^4.5.0"
|
||||
|
||||
"@tryghost/update-check-service@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/update-check-service/-/update-check-service-0.1.0.tgz#ca1277989989968f2b2603a7d3b86e1124025be5"
|
||||
|
@ -1037,6 +1044,17 @@
|
|||
remark-footnotes "^1.0.0"
|
||||
unist-util-visit "^2.0.0"
|
||||
|
||||
"@tryghost/validator@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/validator/-/validator-0.1.0.tgz#f089fed04998a4ceb4957350117f8d9bb626daf0"
|
||||
integrity sha512-Np9EN3RayTOd81GjVna6Zv12LsTz98JlqeXbOnUVzrRphARRJHvNwcKi7Kh4EDqA2MWpYQDiU0+QwP7zyA0Gkg==
|
||||
dependencies:
|
||||
"@tryghost/errors" "^0.2.12"
|
||||
"@tryghost/tpl" "^0.1.2"
|
||||
lodash "^4.17.21"
|
||||
moment-timezone "0.5.23"
|
||||
validator "7.2.0"
|
||||
|
||||
"@tryghost/vhost-middleware@1.0.15":
|
||||
version "1.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/vhost-middleware/-/vhost-middleware-1.0.15.tgz#6f5e7e018fe6d9b09b0f2b7f5294f8133398cbd1"
|
||||
|
|
Loading…
Add table
Reference in a new issue