mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Improved verification logic for Mentions
refs https://github.com/TryGhost/Team/issues/2550 By using cheerio to parse the HTML we can correctly look for elements which use the target URL as the href attribute, rather than doing a plaintext search. This closer to what the spec says.
This commit is contained in:
parent
e14d2e662b
commit
8908a51547
3 changed files with 124 additions and 7 deletions
|
@ -153,8 +153,7 @@ describe('Webmentions (receiving)', function () {
|
|||
`;
|
||||
nock(sourceUrl.origin)
|
||||
.get(sourceUrl.pathname)
|
||||
.reply(200, html, {'Content-Type': 'text/html'})
|
||||
.persist();
|
||||
.reply(200, html, {'Content-Type': 'text/html'});
|
||||
|
||||
testCreatingTheMention: {
|
||||
const processWebmentionJob = jobsService.awaitCompletion('processWebmention');
|
||||
|
@ -352,4 +351,97 @@ describe('Webmentions (receiving)', function () {
|
|||
})
|
||||
.expectStatus(429);
|
||||
});
|
||||
|
||||
it('can verify a webmention <a> link', async function () {
|
||||
const processWebmentionJob = jobsService.awaitCompletion('processWebmention');
|
||||
const targetUrl = new URL(urlUtils.getSiteUrl());
|
||||
const sourceUrl = new URL('http://testpage.com/external-article-2/');
|
||||
const html = `
|
||||
<html><head><title>Test Page</title><meta name="description" content="Test description"><meta name="author" content="John Doe"></head><body><a href="${urlUtils.getSiteUrl()}">your cool website mentioned</a></body></html>
|
||||
`;
|
||||
nock(targetUrl.origin)
|
||||
.head(targetUrl.pathname)
|
||||
.reply(200);
|
||||
|
||||
nock(sourceUrl.origin)
|
||||
.persist()
|
||||
.get(sourceUrl.pathname)
|
||||
.reply(200, html, {'Content-Type': 'text/html'});
|
||||
|
||||
await agent.post('/receive')
|
||||
.body({
|
||||
source: sourceUrl.href,
|
||||
target: targetUrl.href
|
||||
})
|
||||
.expectStatus(202);
|
||||
|
||||
await processWebmentionJob;
|
||||
|
||||
const mention = await models.Mention.findOne({source: 'http://testpage.com/external-article-2/'});
|
||||
|
||||
assert(mention);
|
||||
assert.equal(mention.get('verified'), true);
|
||||
});
|
||||
|
||||
it('can verifiy a webmention <img> link', async function () {
|
||||
const processWebmentionJob = jobsService.awaitCompletion('processWebmention');
|
||||
const targetUrl = new URL(urlUtils.getSiteUrl());
|
||||
const sourceUrl = new URL('http://testpage.com/external-article-2/');
|
||||
const html = `
|
||||
<html><head><title>Test Page</title><meta name="description" content="Test description"><meta name="author" content="John Doe"></head><body><img src="${urlUtils.getSiteUrl()}"></body></html>
|
||||
`;
|
||||
nock(targetUrl.origin)
|
||||
.head(targetUrl.pathname)
|
||||
.reply(200);
|
||||
|
||||
nock(sourceUrl.origin)
|
||||
.persist()
|
||||
.get(sourceUrl.pathname)
|
||||
.reply(200, html, {'Content-Type': 'text/html'});
|
||||
|
||||
await agent.post('/receive')
|
||||
.body({
|
||||
source: sourceUrl.href,
|
||||
target: targetUrl.href
|
||||
})
|
||||
.expectStatus(202);
|
||||
|
||||
await processWebmentionJob;
|
||||
|
||||
const mention = await models.Mention.findOne({source: 'http://testpage.com/external-article-2/'});
|
||||
|
||||
assert(mention);
|
||||
assert.equal(mention.get('verified'), true);
|
||||
});
|
||||
|
||||
it('can verify a webmention <video> link', async function () {
|
||||
const processWebmentionJob = jobsService.awaitCompletion('processWebmention');
|
||||
const targetUrl = new URL(urlUtils.getSiteUrl());
|
||||
const sourceUrl = new URL('http://testpage.com/external-article-2/');
|
||||
const html = `
|
||||
<html><head><title>Test Page</title><meta name="description" content="Test description"><meta name="author" content="John Doe"></head><body><video src="${urlUtils.getSiteUrl()}"></body></html>
|
||||
`;
|
||||
nock(targetUrl.origin)
|
||||
.head(targetUrl.pathname)
|
||||
.reply(200);
|
||||
|
||||
nock(sourceUrl.origin)
|
||||
.persist()
|
||||
.get(sourceUrl.pathname)
|
||||
.reply(200, html, {'Content-Type': 'text/html'});
|
||||
|
||||
await agent.post('/receive')
|
||||
.body({
|
||||
source: sourceUrl.href,
|
||||
target: targetUrl.href
|
||||
})
|
||||
.expectStatus(202);
|
||||
|
||||
await processWebmentionJob;
|
||||
|
||||
const mention = await models.Mention.findOne({source: 'http://testpage.com/external-article-2/'});
|
||||
|
||||
assert(mention);
|
||||
assert.equal(mention.get('verified'), true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const ObjectID = require('bson-objectid').default;
|
||||
const {ValidationError} = require('@tryghost/errors');
|
||||
const MentionCreatedEvent = require('./MentionCreatedEvent');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = class Mention {
|
||||
/** @type {Array} */
|
||||
|
@ -22,11 +23,9 @@ module.exports = class Mention {
|
|||
* @param {string} html
|
||||
*/
|
||||
verify(html) {
|
||||
if (html.includes(this.target.href)) {
|
||||
this.#verified = true;
|
||||
} else {
|
||||
this.#verified = false;
|
||||
}
|
||||
const $ = cheerio.load(html);
|
||||
const hasTargetUrl = $('a[href*="' + this.target.href + '"], img[src*="' + this.target.href + '"], video[src*="' + this.target.href + '"]').length > 0;
|
||||
this.#verified = hasTargetUrl;
|
||||
}
|
||||
|
||||
/** @type {URL} */
|
||||
|
|
|
@ -44,6 +44,32 @@ describe('Mention', function () {
|
|||
mention.verify('<a href="https://not-da-target.com">');
|
||||
assert(!mention.verified);
|
||||
});
|
||||
it('Does check for Image targets', async function () {
|
||||
const mention = await Mention.create({
|
||||
...validInput,
|
||||
target: 'https://target.com/image.jpg'
|
||||
});
|
||||
assert(!mention.verified);
|
||||
|
||||
mention.verify('<img src="https://target.com/image.jpg">');
|
||||
assert(mention.verified);
|
||||
|
||||
mention.verify('<img src="https://not-da-target.com/image.jpg">');
|
||||
assert(!mention.verified);
|
||||
});
|
||||
it('Does check for Video targets', async function () {
|
||||
const mention = await Mention.create({
|
||||
...validInput,
|
||||
target: 'https://target.com/video.mp4'
|
||||
});
|
||||
assert(!mention.verified);
|
||||
|
||||
mention.verify('<video src="https://target.com/video.mp4">');
|
||||
assert(mention.verified);
|
||||
|
||||
mention.verify('<video src="https://not-da-target.com/video.mp4">');
|
||||
assert(!mention.verified);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create', function () {
|
||||
|
|
Loading…
Add table
Reference in a new issue