From 786e0ac9c563eb5655c2ae5292cf8b108e6692a0 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Fri, 7 Oct 2022 20:13:42 +0100 Subject: [PATCH] Updated ValidationEngine to support bare native class models (#15567) no issue - if a plain native class instance with tracked properties is validated against the `ValidationEngine` and it's associated validators would cause errors by assuming that the instance has a `.get()` method - updated all model access in `ValidationEngine` and the validators to use direct property access which works for both native class and `EmberObject` instances --- ghost/admin/app/mixins/validation-engine.js | 8 ++-- ghost/admin/app/validators/invite-user.js | 12 ++--- ghost/admin/app/validators/member.js | 8 ++-- ghost/admin/app/validators/mixins/password.js | 22 ++++----- ghost/admin/app/validators/nav-item.js | 14 +++--- ghost/admin/app/validators/new-user.js | 14 +++--- ghost/admin/app/validators/reset.js | 8 ++-- ghost/admin/app/validators/setting.js | 18 +++---- ghost/admin/app/validators/setup.js | 6 +-- ghost/admin/app/validators/signin.js | 22 ++++----- ghost/admin/app/validators/snippet.js | 6 +-- ghost/admin/app/validators/subscriber.js | 14 +++--- ghost/admin/app/validators/tag-settings.js | 24 +++++----- .../admin/app/validators/tier-benefit-item.js | 6 +-- ghost/admin/app/validators/user.js | 48 +++++++++---------- 15 files changed, 115 insertions(+), 115 deletions(-) diff --git a/ghost/admin/app/mixins/validation-engine.js b/ghost/admin/app/mixins/validation-engine.js index 79d6f9e4e7..f249db5957 100644 --- a/ghost/admin/app/mixins/validation-engine.js +++ b/ghost/admin/app/mixins/validation-engine.js @@ -107,8 +107,8 @@ export default Mixin.create({ model = this.model; } - type = this.validationType || model.get('validationType'); - validator = this.get(`validators.${type}`) || model.get(`validators.${type}`); + type = this.validationType || model.validationType; + validator = this.get(`validators.${type}`) || model.validators[type]; hasValidated = this.hasValidated; opts.validationType = type; @@ -123,9 +123,9 @@ export default Mixin.create({ if (opts.property) { // If property isn't in `hasValidated`, add it to mark that this field can show a validation result hasValidated.addObject(opts.property); - model.get('errors').remove(opts.property); + model.errors.remove(opts.property); } else { - model.get('errors').clear(); + model.errors.clear(); } passed = validator.check(model, opts.property); diff --git a/ghost/admin/app/validators/invite-user.js b/ghost/admin/app/validators/invite-user.js index e3c6a2deb9..469793e280 100644 --- a/ghost/admin/app/validators/invite-user.js +++ b/ghost/admin/app/validators/invite-user.js @@ -6,23 +6,23 @@ export default BaseValidator.create({ properties: ['email', 'role'], email(model) { - let email = model.get('email'); + let email = model.email; if (isBlank(email)) { - model.get('errors').add('email', 'Please enter an email.'); + model.errors.add('email', 'Please enter an email.'); this.invalidate(); } else if (!validator.isEmail(email)) { - model.get('errors').add('email', 'Invalid Email.'); + model.errors.add('email', 'Invalid Email.'); this.invalidate(); } }, role(model) { - let role = model.get('role'); + let role = model.role; if (isBlank(role)) { - model.get('errors').add('role', 'Please select a role.'); - model.get('hasValidated').pushObject('role'); + model.errors.add('role', 'Please select a role.'); + model.hasValidated.pushObject('role'); this.invalidate(); } } diff --git a/ghost/admin/app/validators/member.js b/ghost/admin/app/validators/member.js index dc0ec14bb2..ee32c5ae69 100644 --- a/ghost/admin/app/validators/member.js +++ b/ghost/admin/app/validators/member.js @@ -13,7 +13,7 @@ export default BaseValidator.create({ }, email(model) { - let email = model.get('email'); + let email = model.email; if (isBlank(email)) { model.errors.add('email', 'Please enter an email.'); @@ -27,17 +27,17 @@ export default BaseValidator.create({ this.invalidate(); } - model.get('hasValidated').addObject('email'); + model.hasValidated.addObject('email'); }, note(model) { - let note = model.get('note'); + let note = model.note; if (!validator.isLength(note || '', 0, 500)) { model.errors.add('note', 'Note is too long.'); this.invalidate(); } - model.get('hasValidated').addObject('note'); + model.hasValidated.addObject('note'); } }); diff --git a/ghost/admin/app/validators/mixins/password.js b/ghost/admin/app/validators/mixins/password.js index 95f7084a6f..821a82a135 100644 --- a/ghost/admin/app/validators/mixins/password.js +++ b/ghost/admin/app/validators/mixins/password.js @@ -49,13 +49,13 @@ export default Mixin.create({ }, passwordValidation(model, password, errorTarget) { - let blogUrl = model.get('config.blogUrl') || window.location.host; - let blogTitle = model.get('blogTitle') || model.get('config.blogTitle'); + let blogUrl = model.config?.blogUrl || window.location.host; + let blogTitle = model.blogTitle || model.config?.blogTitle; let blogUrlWithSlash; // the password that needs to be validated can differ from the password in the // passed model, e. g. for password changes or reset. - password = password || model.get('password'); + password = password || model.password; errorTarget = errorTarget || 'password'; blogUrl = blogUrl.replace(/^http(s?):\/\//, ''); @@ -65,7 +65,7 @@ export default Mixin.create({ // password must be longer than 10 characters if (!validator.isLength(password || '', 10)) { - model.get('errors').add(errorTarget, 'Password must be at least 10 characters long.'); + model.errors.add(errorTarget, 'Password must be at least 10 characters long.'); return this.invalidate(); } @@ -74,40 +74,40 @@ export default Mixin.create({ // dissallow password from badPasswords list (e. g. '1234567890') BAD_PASSWORDS.forEach((badPassword) => { if (badPassword === password) { - model.get('errors').add(errorTarget, 'Sorry, you cannot use an insecure password.'); + model.errors.add(errorTarget, 'Sorry, you cannot use an insecure password.'); this.invalidate(); } }); // password must not match with users' email - if (password.toLowerCase() === model.get('email').toLowerCase()) { - model.get('errors').add(errorTarget, 'Sorry, you cannot use an insecure password.'); + if (password.toLowerCase() === model.email.toLowerCase()) { + model.errors.add(errorTarget, 'Sorry, you cannot use an insecure password.'); this.invalidate(); } // password must not contain the words 'ghost', 'password', or 'passw0rd' DISALLOWED_PASSWORDS.forEach((disallowedPassword) => { if (password.toLowerCase().indexOf(disallowedPassword) >= 0) { - model.get('errors').add(errorTarget, 'Sorry, you cannot use an insecure password.'); + model.errors.add(errorTarget, 'Sorry, you cannot use an insecure password.'); this.invalidate(); } }); // password must not match with blog title if (password.toLowerCase() === blogTitle) { - model.get('errors').add(errorTarget, 'Sorry, you cannot use an insecure password.'); + model.errors.add(errorTarget, 'Sorry, you cannot use an insecure password.'); this.invalidate(); } // password must not match with blog URL (without protocol, with or without trailing slash) if (password.toLowerCase() === blogUrl || password.toLowerCase() === blogUrlWithSlash) { - model.get('errors').add(errorTarget, 'Sorry, you cannot use an insecure password.'); + model.errors.add(errorTarget, 'Sorry, you cannot use an insecure password.'); this.invalidate(); } // dissallow passwords where 50% or more of characters are the same if (!this._characterOccurance(password)) { - model.get('errors').add(errorTarget, 'Sorry, you cannot use an insecure password.'); + model.errors.add(errorTarget, 'Sorry, you cannot use an insecure password.'); this.invalidate(); } } diff --git a/ghost/admin/app/validators/nav-item.js b/ghost/admin/app/validators/nav-item.js index a184c7e913..f6d0cacc7e 100644 --- a/ghost/admin/app/validators/nav-item.js +++ b/ghost/admin/app/validators/nav-item.js @@ -6,11 +6,11 @@ export default BaseValidator.create({ properties: ['label', 'url'], label(model) { - let label = model.get('label'); - let hasValidated = model.get('hasValidated'); + let label = model.label; + let hasValidated = model.hasValidated; if (isBlank(label)) { - model.get('errors').add('label', 'You must specify a label'); + model.errors.add('label', 'You must specify a label'); this.invalidate(); } @@ -18,18 +18,18 @@ export default BaseValidator.create({ }, url(model) { - let url = model.get('url'); - let hasValidated = model.get('hasValidated'); + let url = model.url; + let hasValidated = model.hasValidated; /* eslint-disable camelcase */ let validatorOptions = {require_protocol: true}; /* eslint-enable camelcase */ let urlRegex = new RegExp(/^(\/|#|[a-zA-Z0-9-]+:)/); if (isBlank(url)) { - model.get('errors').add('url', 'You must specify a URL or relative path'); + model.errors.add('url', 'You must specify a URL or relative path'); this.invalidate(); } else if (url.match(/\s/) || (!validator.isURL(url, validatorOptions) && !url.match(urlRegex))) { - model.get('errors').add('url', 'You must specify a valid URL or relative path'); + model.errors.add('url', 'You must specify a valid URL or relative path'); this.invalidate(); } diff --git a/ghost/admin/app/validators/new-user.js b/ghost/admin/app/validators/new-user.js index 703367c6a6..2ea6c7da50 100644 --- a/ghost/admin/app/validators/new-user.js +++ b/ghost/admin/app/validators/new-user.js @@ -10,27 +10,27 @@ export default BaseValidator.extend(PasswordValidatorMixin, { }, name(model) { - let name = model.get('name'); + let name = model.name; if (!validator.isLength(name || '', 1)) { - model.get('errors').add('name', 'Please enter a name.'); - model.get('hasValidated').addObject('email'); + model.errors.add('name', 'Please enter a name.'); + model.hasValidated.addObject('email'); this.invalidate(); } }, email(model) { - let email = model.get('email'); + let email = model.email; if (isBlank(email)) { - model.get('errors').add('email', 'Please enter an email.'); + model.errors.add('email', 'Please enter an email.'); this.invalidate(); } else if (!validator.isEmail(email)) { - model.get('errors').add('email', 'Invalid Email.'); + model.errors.add('email', 'Invalid Email.'); this.invalidate(); } - model.get('hasValidated').addObject('email'); + model.hasValidated.addObject('email'); }, password(model) { diff --git a/ghost/admin/app/validators/reset.js b/ghost/admin/app/validators/reset.js index 9740cb1e00..e9d74bc967 100644 --- a/ghost/admin/app/validators/reset.js +++ b/ghost/admin/app/validators/reset.js @@ -10,14 +10,14 @@ const resetValidator = BaseValidator.extend(PasswordValidatorMixin, { }, newPassword(model) { - let p1 = model.get('newPassword'); - let p2 = model.get('ne2Password'); + let p1 = model.newPassword; + let p2 = model.ne2Password; if (isBlank(p1)) { - model.get('errors').add('newPassword', 'Please enter a password.'); + model.errors.add('newPassword', 'Please enter a password.'); this.invalidate(); } else if (!validator.equals(p1, p2 || '')) { - model.get('errors').add('ne2Password', 'The two new passwords don\'t match.'); + model.errors.add('ne2Password', 'The two new passwords don\'t match.'); this.invalidate(); } diff --git a/ghost/admin/app/validators/setting.js b/ghost/admin/app/validators/setting.js index e71fd699ab..fbbbeec460 100644 --- a/ghost/admin/app/validators/setting.js +++ b/ghost/admin/app/validators/setting.js @@ -5,38 +5,38 @@ import {isBlank} from '@ember/utils'; export default BaseValidator.create({ properties: ['title', 'description', 'password', 'slackUrl'], title(model) { - let title = model.get('title'); + let title = model.title; if (!validator.isLength(title || '', 0, 150)) { - model.get('errors').add('title', 'Title is too long'); + model.errors.add('title', 'Title is too long'); this.invalidate(); } }, description(model) { - let desc = model.get('description'); + let desc = model.description; if (!validator.isLength(desc || '', 0, 200)) { - model.get('errors').add('description', 'Description is too long'); + model.errors.add('description', 'Description is too long'); this.invalidate(); } }, password(model) { - let isPrivate = model.get('isPrivate'); - let password = model.get('password'); + let isPrivate = model.isPrivate; + let password = model.password; if (isPrivate && password === '') { - model.get('errors').add('password', 'Password must be supplied'); + model.errors.add('password', 'Password must be supplied'); this.invalidate(); } }, slackUrl(model) { - let slackUrl = model.get('slackUrl'); + let slackUrl = model.slackUrl; if (!isBlank(slackUrl) && !validator.isURL(slackUrl, {require_protocol: true})) { - model.get('errors').add( + model.errors.add( 'slackUrl', 'The URL must be in a format like https://hooks.slack.com/services/' ); diff --git a/ghost/admin/app/validators/setup.js b/ghost/admin/app/validators/setup.js index 6d0042ea29..6a980caa81 100644 --- a/ghost/admin/app/validators/setup.js +++ b/ghost/admin/app/validators/setup.js @@ -5,15 +5,15 @@ export default NewUserValidator.create({ properties: ['name', 'email', 'password', 'blogTitle'], blogTitle(model) { - let blogTitle = model.get('blogTitle'); + let blogTitle = model.blogTitle; if (!validator.isLength(blogTitle || '', 1)) { - model.get('errors').add('blogTitle', 'Please enter a site title.'); + model.errors.add('blogTitle', 'Please enter a site title.'); this.invalidate(); } if (!validator.isLength(blogTitle || '', 0, 150)) { - model.get('errors').add('blogTitle', 'Title is too long'); + model.errors.add('blogTitle', 'Title is too long'); this.invalidate(); } } diff --git a/ghost/admin/app/validators/signin.js b/ghost/admin/app/validators/signin.js index 3c59a9da42..2b326b83f9 100644 --- a/ghost/admin/app/validators/signin.js +++ b/ghost/admin/app/validators/signin.js @@ -7,43 +7,43 @@ export default BaseValidator.create({ invalidMessage: 'Email address is not valid', identification(model) { - let id = model.get('identification'); + let id = model.identification; if (!isBlank(id) && !validator.isEmail(id)) { - model.get('errors').add('identification', this.invalidMessage); + model.errors.add('identification', this.invalidMessage); this.invalidate(); } }, signin(model) { - let id = model.get('identification'); - let password = model.get('password'); + let id = model.identification; + let password = model.password; - model.get('errors').clear(); + model.errors.clear(); if (isBlank(id)) { - model.get('errors').add('identification', 'Please enter an email'); + model.errors.add('identification', 'Please enter an email'); this.invalidate(); } if (!isBlank(id) && !validator.isEmail(id)) { - model.get('errors').add('identification', this.invalidMessage); + model.errors.add('identification', this.invalidMessage); this.invalidate(); } if (isBlank(password)) { - model.get('errors').add('password', 'Please enter a password'); + model.errors.add('password', 'Please enter a password'); this.invalidate(); } }, forgotPassword(model) { - let id = model.get('identification'); + let id = model.identification; - model.get('errors').clear(); + model.errors.clear(); if (isBlank(id) || !validator.isEmail(id)) { - model.get('errors').add('identification', this.invalidMessage); + model.errors.add('identification', this.invalidMessage); this.invalidate(); } } diff --git a/ghost/admin/app/validators/snippet.js b/ghost/admin/app/validators/snippet.js index 7252d8487e..3715dfaef4 100644 --- a/ghost/admin/app/validators/snippet.js +++ b/ghost/admin/app/validators/snippet.js @@ -18,14 +18,14 @@ export default BaseValidator.create({ this.invalidate(); } - model.get('hasValidated').addObject('name'); + model.hasValidated.addObject('name'); }, mobiledoc(model) { - if (isBlank(model.get('mobiledoc'))) { + if (isBlank(model.mobiledoc)) { model.errors.add('mobiledoc', 'Content cannot be blank.'); this.invalidate(); } - model.get('hasValidated').addObject('mobiledoc'); + model.hasValidated.addObject('mobiledoc'); } }); diff --git a/ghost/admin/app/validators/subscriber.js b/ghost/admin/app/validators/subscriber.js index b586361b6e..10a7f3b8bf 100644 --- a/ghost/admin/app/validators/subscriber.js +++ b/ghost/admin/app/validators/subscriber.js @@ -6,19 +6,19 @@ export default BaseValidator.create({ properties: ['email'], email(model) { - let email = model.get('email'); + let email = model.email; if (isBlank(email)) { - model.get('errors').add('email', 'Please enter an email.'); - model.get('hasValidated').pushObject('email'); + model.errors.add('email', 'Please enter an email.'); + model.hasValidated.pushObject('email'); this.invalidate(); } else if (!validator.isEmail(email)) { - model.get('errors').add('email', 'Invalid email.'); - model.get('hasValidated').pushObject('email'); + model.errors.add('email', 'Invalid email.'); + model.hasValidated.pushObject('email'); this.invalidate(); } else if (!validator.isLength(email, 0, 191)) { - model.get('errors').add('email', 'Email is too long'); - model.get('hasValidated').pushObject('email'); + model.errors.add('email', 'Email is too long'); + model.hasValidated.pushObject('email'); this.invalidate(); } } diff --git a/ghost/admin/app/validators/tag-settings.js b/ghost/admin/app/validators/tag-settings.js index 948a44d87a..9946987b58 100644 --- a/ghost/admin/app/validators/tag-settings.js +++ b/ghost/admin/app/validators/tag-settings.js @@ -6,52 +6,52 @@ export default BaseValidator.create({ properties: ['name', 'slug', 'description', 'metaTitle', 'metaDescription'], name(model) { - let name = model.get('name'); + let name = model.name; if (isBlank(name)) { - model.get('errors').add('name', 'You must specify a name for the tag.'); + model.errors.add('name', 'You must specify a name for the tag.'); this.invalidate(); } else if (name.match(/^,/)) { - model.get('errors').add('name', 'Tag names can\'t start with commas.'); + model.errors.add('name', 'Tag names can\'t start with commas.'); this.invalidate(); } else if (!validator.isLength(name, 0, 191)) { - model.get('errors').add('name', 'Tag names cannot be longer than 191 characters.'); + model.errors.add('name', 'Tag names cannot be longer than 191 characters.'); this.invalidate(); } }, slug(model) { - let slug = model.get('slug'); + let slug = model.slug; if (!validator.isLength(slug || '', 0, 191)) { - model.get('errors').add('slug', 'URL cannot be longer than 191 characters.'); + model.errors.add('slug', 'URL cannot be longer than 191 characters.'); this.invalidate(); } }, description(model) { - let description = model.get('description'); + let description = model.description; if (!validator.isLength(description || '', 0, 500)) { - model.get('errors').add('description', 'Description cannot be longer than 500 characters.'); + model.errors.add('description', 'Description cannot be longer than 500 characters.'); this.invalidate(); } }, metaTitle(model) { - let metaTitle = model.get('metaTitle'); + let metaTitle = model.metaTitle; if (!validator.isLength(metaTitle || '', 0, 300)) { - model.get('errors').add('metaTitle', 'Meta Title cannot be longer than 300 characters.'); + model.errors.add('metaTitle', 'Meta Title cannot be longer than 300 characters.'); this.invalidate(); } }, metaDescription(model) { - let metaDescription = model.get('metaDescription'); + let metaDescription = model.metaDescription; if (!validator.isLength(metaDescription || '', 0, 500)) { - model.get('errors').add('metaDescription', 'Meta Description cannot be longer than 500 characters.'); + model.errors.add('metaDescription', 'Meta Description cannot be longer than 500 characters.'); this.invalidate(); } } diff --git a/ghost/admin/app/validators/tier-benefit-item.js b/ghost/admin/app/validators/tier-benefit-item.js index 845299f94a..41aa211183 100644 --- a/ghost/admin/app/validators/tier-benefit-item.js +++ b/ghost/admin/app/validators/tier-benefit-item.js @@ -5,11 +5,11 @@ export default BaseValidator.create({ properties: ['name'], name(model) { - let name = model.get('name'); - let hasValidated = model.get('hasValidated'); + let name = model.name; + let hasValidated = model.hasValidated; if (isBlank(name)) { - model.get('errors').add('name', 'Please enter a benefit'); + model.errors.add('name', 'Please enter a benefit'); this.invalidate(); } diff --git a/ghost/admin/app/validators/user.js b/ghost/admin/app/validators/user.js index b6cd31d570..437b38c437 100644 --- a/ghost/admin/app/validators/user.js +++ b/ghost/admin/app/validators/user.js @@ -10,68 +10,68 @@ const userValidator = BaseValidator.extend(PasswordValidatorMixin, { }, isActive(model) { - return (model.get('status') === 'active'); + return (model.status === 'active'); }, name(model) { - let name = model.get('name'); + let name = model.name; if (this.isActive(model)) { if (isBlank(name)) { - model.get('errors').add('name', 'Please enter a name.'); + model.errors.add('name', 'Please enter a name.'); this.invalidate(); } else if (!validator.isLength(name, 0, 191)) { - model.get('errors').add('name', 'Name is too long'); + model.errors.add('name', 'Name is too long'); this.invalidate(); } } }, bio(model) { - let bio = model.get('bio'); + let bio = model.bio; if (this.isActive(model)) { if (!validator.isLength(bio || '', 0, 200)) { - model.get('errors').add('bio', 'Bio is too long'); + model.errors.add('bio', 'Bio is too long'); this.invalidate(); } } }, email(model) { - let email = model.get('email'); + let email = model.email; if (!validator.isEmail(email || '')) { - model.get('errors').add('email', 'Please supply a valid email address'); + model.errors.add('email', 'Please supply a valid email address'); this.invalidate(); } if (!validator.isLength(email || '', 0, 191)) { - model.get('errors').add('email', 'Email is too long'); + model.errors.add('email', 'Email is too long'); this.invalidate(); } }, location(model) { - let location = model.get('location'); + let location = model.location; if (this.isActive(model)) { if (!validator.isLength(location || '', 0, 150)) { - model.get('errors').add('location', 'Location is too long'); + model.errors.add('location', 'Location is too long'); this.invalidate(); } } }, website(model) { - let website = model.get('website'); + let website = model.website; // eslint-disable-next-line camelcase let isInvalidWebsite = !validator.isURL(website || '', {require_protocol: false}) || !validator.isLength(website || '', 0, 2000); if (this.isActive(model)) { if (!isBlank(website) && isInvalidWebsite) { - model.get('errors').add('website', 'Website is not a valid url'); + model.errors.add('website', 'Website is not a valid url'); this.invalidate(); } } @@ -79,30 +79,30 @@ const userValidator = BaseValidator.extend(PasswordValidatorMixin, { roles(model) { if (!this.isActive(model)) { - let roles = model.get('roles'); + let roles = model.roles; if (roles.length < 1) { - model.get('errors').add('role', 'Please select a role'); + model.errors.add('role', 'Please select a role'); this.invalidate(); } } }, passwordChange(model) { - let newPassword = model.get('newPassword'); - let ne2Password = model.get('ne2Password'); + let newPassword = model.newPassword; + let ne2Password = model.ne2Password; // validation only marks the requested property as validated so we // have to add properties manually - model.get('hasValidated').addObject('newPassword'); - model.get('hasValidated').addObject('ne2Password'); + model.hasValidated.addObject('newPassword'); + model.hasValidated.addObject('ne2Password'); if (isBlank(newPassword) && isBlank(ne2Password)) { - model.get('errors').add('newPassword', 'Sorry, passwords can\'t be blank'); + model.errors.add('newPassword', 'Sorry, passwords can\'t be blank'); this.invalidate(); } else { if (!validator.equals(newPassword, ne2Password || '')) { - model.get('errors').add('ne2Password', 'Your new passwords do not match'); + model.errors.add('ne2Password', 'Your new passwords do not match'); this.invalidate(); } @@ -111,16 +111,16 @@ const userValidator = BaseValidator.extend(PasswordValidatorMixin, { }, ownPasswordChange(model) { - let oldPassword = model.get('password'); + let oldPassword = model.password; this.passwordChange(model); // validation only marks the requested property as validated so we // have to add properties manually - model.get('hasValidated').addObject('password'); + model.hasValidated.addObject('password'); if (isBlank(oldPassword)) { - model.get('errors').add('password', 'Your current password is required to set a new one'); + model.errors.add('password', 'Your current password is required to set a new one'); this.invalidate(); } }