0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

Updated Mention entity validation of properties

Based on a discussion in slack we want to make all metadata properties optional,
with the exception of the title, which will default to the host of the source
URL if it's missing.

This is so that we can accept as many webmentions as possible and convert them
into Mentions. If we were to have strictly validation, we'd end up having to
drop webmentions that didn't match our criteria, and lose important data.

Giving the title a default allows us to provide a consistent UI experience too.
This commit is contained in:
Fabien "egg" O'Carroll 2023-01-19 19:07:01 +07:00
parent 743da542d0
commit 3a0e0831ec
2 changed files with 29 additions and 23 deletions

View file

@ -165,10 +165,13 @@ module.exports = class Mention {
}
}
const sourceTitle = validateString(data.sourceTitle, 191, 'sourceTitle');
const sourceExcerpt = validateString(data.sourceExcerpt, 1000, 'sourceExcerpt');
const sourceSiteTitle = validateString(data.sourceSiteTitle, 191, 'sourceSiteTitle', false);
const sourceAuthor = validateString(data.sourceAuthor, 191, 'sourceAuthor', false);
let sourceTitle = validateString(data.sourceTitle, 2000, 'sourceTitle');
if (sourceTitle === null) {
sourceTitle = source.host;
}
const sourceExcerpt = validateString(data.sourceExcerpt, 2000, 'sourceExcerpt');
const sourceSiteTitle = validateString(data.sourceSiteTitle, 2000, 'sourceSiteTitle');
const sourceAuthor = validateString(data.sourceAuthor, 2000, 'sourceAuthor');
let sourceFavicon = null;
if (data.sourceFavicon instanceof URL) {
@ -201,15 +204,9 @@ module.exports = class Mention {
}
};
function validateString(value, maxlength, name, required = true) {
function validateString(value, maxlength, name) {
if (!value) {
if (required) {
throw new ValidationError({
message: `Missing ${name} for Mention`
});
} else {
return null;
}
return null;
}
if (typeof value !== 'string') {
@ -218,11 +215,5 @@ function validateString(value, maxlength, name, required = true) {
});
}
if (value.length > maxlength) {
throw new ValidationError({
message: `${name} must be less than ${maxlength + 1} characters`
});
}
return value;
return value.trim().slice(0, maxlength);
}

View file

@ -41,12 +41,8 @@ describe('Mention', function () {
{target: 'Not a valid target'},
{timestamp: 'Not a valid timestamp'},
{resourceId: 'Invalid resourceId'},
{sourceTitle: null},
{sourceTitle: 123},
{sourceTitle: Array.from({length: 200}).join('A')},
{sourceExcerpt: null},
{sourceExcerpt: 123},
{sourceExcerpt: Array.from({length: 3000}).join('A')},
{sourceFavicon: 'Invalid source favicon'},
{sourceFeaturedImage: 'Invalid source featured image'}
];
@ -90,5 +86,24 @@ describe('Mention', function () {
});
}
});
it('Will trim titles which are too long', async function () {
const mention = await Mention.create({
...validInput,
sourceTitle: Array.from({length: 3000}).join('A')
});
assert(mention.sourceTitle.length === 2000);
});
it('Will default the title to the host of the source URL if missing', async function () {
const mention = await Mention.create({
...validInput,
sourceTitle: null
});
assert(mention.sourceTitle);
assert(mention.sourceTitle === 'source.com');
});
});
});